package com.winning.pmph.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.winning.pmph.entity.*;
import com.winning.pmph.enumeration.KnowledgeSystem;
import com.winning.pmph.mapper.*;
import com.winning.pmph.utils.*;
import com.winning.pmph.vo.CalculateData;
import com.winning.pmph.vo.NameSuggestion;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 吴笛
 */
@Slf4j
@Component
@Transactional
public class CalculatorService extends ServiceImpl<MedicalCalculatorMapper, MedicalCalculator> {
    @Resource
    private MedicalCalculatorMapper medicalCalculatorMapper;
    @Resource
    private MedicalCalculatorComputationFormulatorMapper medicalCalculatorComputationFormulatorMapper;
    @Resource
    private MedicalCalculatorComputationItemMapper medicalCalculatorComputationItemMapper;
    @Resource
    private MedicalCalculatorComputationMapper medicalCalculatorComputationMapper;
    @Resource
    private MedicalCalculatorFieldMapper medicalCalculatorFieldMapper;
    @Resource
    private MedicalCalculatorLibFieldMapper medicalCalculatorLibFieldMapper;
    @Resource
    private MedicalCalculatorResultItemMapper medicalCalculatorResultItemMapper;
    @Resource
    private MedicalCalculatorResultMapper medicalCalculatorResultMapper;
    @Resource
    private MedicalCalculatorScoreItemMapper medicalCalculatorScoreItemMapper;
    @Resource
    private MedicalCalculatorScoreMapper medicalCalculatorScoreMapper;
    @Resource
    private MedicalCalculatorScoreTypeMapper medicalCalculatorScoreTypeMapper;
    @Resource
    private ReleasedMedicalCalculatorComputationFormulatorMapper releasedMedicalCalculatorComputationFormulatorMapper;
    @Resource
    private ReleasedMedicalCalculatorComputationItemMapper releasedMedicalCalculatorComputationItemMapper;
    @Resource
    private ReleasedMedicalCalculatorComputationMapper releasedMedicalCalculatorComputationMapper;
    @Resource
    private ReleasedMedicalCalculatorFieldMapper releasedMedicalCalculatorFieldMapper;
    @Resource
    private ReleasedMedicalCalculatorMapper releasedMedicalCalculatorMapper;
    @Resource
    private ReleasedMedicalCalculatorResultMapper releasedMedicalCalculatorResultMapper;
    @Resource
    private ReleasedMedicalCalculatorResultItemMapper releasedMedicalCalculatorResultItemMapper;
    @Resource
    private ReleasedMedicalCalculatorScoreMapper releasedMedicalCalculatorScoreMapper;
    @Resource
    private ReleasedMedicalCalculatorScoreItemMapper releasedMedicalCalculatorScoreItemMapper;
    @Resource
    private ReleasedMedicalCalculatorScoreTypeMapper releasedMedicalCalculatorScoreTypeMapper;
    @Resource
    private TagService tagService;
    @Resource
    private TagMapper tagMapper;
    @Resource
    private KnowledgeLibService knowledgeLibService;
    @Resource
    private KnowledgeSyncStatusService knowledgeSyncStatusService;
    @Resource
    private HistoryMapper historyMapper;
    @Resource
    private TaskService taskService;
    @Resource
    private TaskItemService taskItemService;
    @Resource
    private PlatformKnowledgeLibMapper platformKnowledgeLibMapper;
    @Resource
    private PlatformService platformService;
    @Resource
    private RocketMQProducerService rocketMQProducerService;

    public List<Map<String, Object>> getAllFormulaData() {
        List<Map<String, Object>> result = new ArrayList<>();
        List<ReleasedMedicalCalculator> releasedMedicalCalculators = releasedMedicalCalculatorMapper.selectAll();
        for (ReleasedMedicalCalculator releasedMedicalCalculator : releasedMedicalCalculators) {
            result.add(getReleaseCalculatorDataById(releasedMedicalCalculator.getId()));
        }
        return result;
    }

    /**
     * 重构医学计算器查询列表
     *
     * @param currentPage
     * @param pageNum
     * @param tagId
     * @param name
     * @return
     */

    public List<MedicalCalculator> queryMedicalCalculatorList(int currentPage, int pageNum, String tagId, String name, String status, String type) {
        String sql = "select * from medical_calculator where 1=1";
        if (StringUtils.isNotBlank(name)) {
            sql += " and  formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(tagId) && !"\"\"".equals(tagId) && !"[]".equals(tagId)) {
            String tagSql = "select medical_calc_id from medical_calculator_field where property in ('" + tagId + "')";
            List<MedicalCalculatorField> medicalCalculatorFieldList = medicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId2 = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(MedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";

            sql += " and id in" + tagId2;

        }
        if (StringUtils.isNotBlank(status)) {
            sql += " and data_status = '" + status + "'";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and formula_type = '" + type + "'";
        }
        sql += " order by updated_time desc,id limit " + currentPage * pageNum + " , " + pageNum;

        List<MedicalCalculator> list = medicalCalculatorMapper.executeMultiSelect(sql);
        String calculatorIds = "('" + org.apache.commons.lang.StringUtils.join(list.stream().map(MedicalCalculator::getId).collect(Collectors.toList()), "','") + "')";
        String fieldSql = "select * from medical_calculator_field where medical_calc_id in " + calculatorIds;
        List<MedicalCalculatorField> fieldList = medicalCalculatorFieldMapper.executeMultiSelect(fieldSql);
        List<MedicalCalculatorField> fieldsList = new ArrayList<>();
        for (MedicalCalculatorField field : fieldList) {
            MedicalCalculatorField medicalField = new MedicalCalculatorField();
            List<Tag> tagList = null;
            if (field.getKind() == MedicalCalculatorField.CASCADE) {
                if (!"".equals(field.getProperty()) && !"[]".equals(field.getProperty()) && field.getProperty() != null) {
                    String tagIds = "(" + getTagId(field.getProperty()).replaceAll("\"", "'").replaceAll("\\[", "").replaceAll("]", "") + ")";
                    String tagSql = "select id,name,parent_id,tag_code,old_tag_code,enable,level from tag where id in " + tagIds;
                    tagList = tagMapper.executeMultiSelect(tagSql);
                }
                if (CollectionUtils.isNotEmpty(tagList)) {
                    medicalField.setProperty(tagList.stream().map(Tag::getName).collect(Collectors.joining(",")));
                } else {
                    medicalField.setProperty(field.getProperty());
                }
                medicalField.setId(field.getId());
                medicalField.setMedicalCalcId(field.getMedicalCalcId());
                medicalField.setName(field.getName());
                medicalField.setKind(field.getKind());
            }
            fieldsList.add(medicalField);
        }
        list.forEach(medicalCalculator -> {
            medicalCalculator.setMedicalCalculatorFieldList(fieldsList.stream().filter(field -> StringUtils.equals(field.getMedicalCalcId(), medicalCalculator.getId())).collect(Collectors.toList()));
        });
        return list;
    }


    public int getMedicalCalculatorTotalNum(String tagId, String name, String status, String type) {
        String sql = "select * from medical_calculator where 1=1";
        if (StringUtils.isNotBlank(name)) {
            sql += " and  id in(select medical_calc_id from medical_calculator_field where property like '%" + name + "%')";
        }
        if (StringUtils.isNotBlank(tagId) && !"\"\"".equals(tagId) && !"[]".equals(tagId)) {
            String tagSql = "select medical_calc_id from medical_calculator_field where property  in ('" + tagId + "')";
            List<MedicalCalculatorField> medicalCalculatorFieldList = medicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId2 = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(MedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";
            sql += " and id in" + tagId2;
        }
        if (StringUtils.isNotBlank(status)) {
            sql += " and data_status = '" + status + "'";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and formula_type = '" + type + "'";
        }
        sql += " order by updated_time desc";
        List<MedicalCalculator> list = medicalCalculatorMapper.executeMultiSelect(sql);
        return list.size();
    }


    public List<Map<String, Object>> getSubjectOptions(String id) {
        return Utils.getTagCascadeId(id);
    }


    public List<Map<String, Object>> getOptions() {

        return Utils.getTagCascade("学科");
    }

    private void saveMedicalCalculatorResult(String username,
                                             String calculatorSore,
                                             MedicalCalculator medicalCalculator1) {
        JSONArray calculatorSoreArray = JSONArray.parseArray(calculatorSore);
        for (int i = 0; i < calculatorSoreArray.size(); i++) {
            JSONObject calculatorSoreData = calculatorSoreArray.getJSONObject(i);
            String scoreData = calculatorSoreData.getString("scoreData");
            MedicalCalculatorScoreType medicalCalculatorScoreType =
                    saveMedicalCalculatorScoreType(username, medicalCalculator1, calculatorSoreData);
            JSONArray scoreArray = JSONArray.parseArray(scoreData);
            for (int j = 0; j < scoreArray.size(); j++) {
                JSONObject dataJson = scoreArray.getJSONObject(j);
                MedicalCalculatorScore meScore =
                        saveMedicalCalculatorScore(username, medicalCalculatorScoreType, dataJson);
                saveMedicalCalculatorScoreItem(username, meScore, dataJson);
            }
            saveMedicalCalculatorResult(username, calculatorSoreData, medicalCalculatorScoreType.getId());
        }
    }

    private MedicalCalculatorScoreType saveMedicalCalculatorScoreType(String username,
                                                                      MedicalCalculator medicalCalculator1,
                                                                      JSONObject calculatorSoreData) {
        String explain = calculatorSoreData.getString("explain");
        MedicalCalculatorScoreType scoreType = new MedicalCalculatorScoreType();
        scoreType.setCreatedBy(username);
        scoreType.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        scoreType.setUpdatedBy(username);
        scoreType.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        scoreType.setMedicalCalcId(medicalCalculator1.getId());
        scoreType.setExplain(explain);
        return medicalCalculatorScoreTypeMapper.saveBean(scoreType);
    }

    private MedicalCalculatorScore saveMedicalCalculatorScore(String username, MedicalCalculatorScoreType medicalCalculatorScoreType, JSONObject dataJson) {
        String id = dataJson.getString("id");
        String name = dataJson.getString("name");
        String multiple = dataJson.getString("multiple");
        MedicalCalculatorScore medicalCalculatorScore = new MedicalCalculatorScore();
        medicalCalculatorScore.setSort(id);
        medicalCalculatorScore.setMedicalCalcScoreTypeId(medicalCalculatorScoreType.getId());
        medicalCalculatorScore.setName(name);
        medicalCalculatorScore.setType(multiple);
        medicalCalculatorScore.setCreatedBy(username);
        medicalCalculatorScore.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculatorScore.setUpdatedBy(username);
        medicalCalculatorScore.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        return medicalCalculatorScoreMapper.saveBean(medicalCalculatorScore);
    }

    private void saveMedicalCalculatorScoreItem(String username, MedicalCalculatorScore meScore, JSONObject dataJson) {
        //构建评分列项
        String items = dataJson.getString("items");
        JSONArray itemsarry = JSONArray.parseArray(items);
        for (int n = 0; n < itemsarry.size(); n++) {
            JSONObject dataJson1 = itemsarry.getJSONObject(n);
            String itemId = dataJson1.getString("id");
            String describe = dataJson1.getString("describe");
            String score = dataJson1.getString("score");
            MedicalCalculatorScoreItem medicalCalculatorScoreItem = new MedicalCalculatorScoreItem();
            medicalCalculatorScoreItem.setSort(Integer.parseInt(itemId));
            medicalCalculatorScoreItem.setMedicalCalcScoreId(meScore.getId());
            medicalCalculatorScoreItem.setName(describe);
            medicalCalculatorScoreItem.setScore(score);
            medicalCalculatorScoreItem.setCreatedBy(username);
            medicalCalculatorScoreItem.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorScoreItem.setUpdatedBy(username);
            medicalCalculatorScoreItem.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorScoreItemMapper.saveBean(medicalCalculatorScoreItem);
            log.error(describe);
        }
    }

    public String save(String data, boolean isReleased, String taskItemId, String nameSuggestion) {
        JSONObject object = JSONObject.parseObject(data);
        if (isReleased) {
            // 勘误不涉及名称建议
            return saveReleasedMedicalCalculator(object);
        } else {
            return saveTempMedicalCalculator(object, taskItemId, nameSuggestion);
        }
    }

    public void commit(String data, String taskItemId, String nameSuggestion) {
        JSONObject object = JSONObject.parseObject(data);
        String calculatorId = object.getString("id");
        calculatorId = save(data, false, taskItemId, nameSuggestion);
        String user = PMPHAppUtil.getCurrentUserEnName();
        MedicalCalculator calculator = medicalCalculatorMapper.selectById(calculatorId);
        saveHistory(calculator, History.OPERATE_COMMIT);
        updateTaskItem(calculator, "commit", "", taskItemId, nameSuggestion);
    }

    public void pass(String data, String nameSuggestion) {
        JSONObject object = JSONObject.parseObject(data);
        String calculatorId = object.getString("id");
        String taskItemId = getTaskItemIdByCalculatorId(calculatorId);
        save(data, false, taskItemId, nameSuggestion);
        String user = PMPHAppUtil.getCurrentUserEnName();
        MedicalCalculator calculator = medicalCalculatorMapper.selectById(calculatorId);
        saveHistory(calculator, History.OPERATE_PASS);
        updateTaskItem(calculator, "pass", "", taskItemId, nameSuggestion);
    }

    public void reject(String data, String rejectReason, String nameSuggestion) {
        JSONObject object = JSONObject.parseObject(data);
        String calculatorId = object.getString("id");
        String taskItemId = getTaskItemIdByCalculatorId(calculatorId);
        save(data, false, taskItemId, nameSuggestion);
        String user = PMPHAppUtil.getCurrentUserEnName();
        MedicalCalculator calculator = medicalCalculatorMapper.selectById(calculatorId);
        saveHistory(calculator, History.OPERATE_REJECT);
        updateTaskItem(calculator, "reject", rejectReason, taskItemId, nameSuggestion);
    }

    private String getTaskItemIdByCalculatorId(String calculatorId) {
        String sql = "select ti.id from task_item ti left join task t on t.id = ti.task_id " +
                " where ti.knowledge_id = '" + calculatorId + "' " +
                " and t.status !=  " + Task.STATUS_FINISHED +
                " and ti.deleted !=  " + TaskItem.DELETED +
                " and ti.status != " + TaskItem.STATUS_RELEASED;
        @SuppressWarnings("unchecked")
        List<TaskItem> list = taskItemService.getBaseMapper().executeMultiSelect(sql);
        if (list.size() != 1) {
            throw new RuntimeException("医学计算器与子任务不一一对应");
        }
        return list.get(0).getId();
    }

    private String saveReleasedMedicalCalculator(JSONObject object) {
        JSONArray array = object.getJSONArray("items");
        String id = object.getString("id");
        String describe = object.getString("describeContent");
        int formulaType = Integer.parseInt(object.getString("type"));
        String medicalCalculatorData = object.getString("medicalCalculatorData");
        String calculatorSore = object.getString("calculatorSore");
        String user = PMPHAppUtil.getCurrentUserEnName();
        LocalDateTime now = LocalDateTime.now();

        //构建医学计算器实体
        ReleasedMedicalCalculator releasedMedicalCalculator =
                saveReleasedMedicalCalculator(array, id, describe, formulaType, user, now);
        // 富文本 图片迁移;
        updateProperty(null, releasedMedicalCalculator, TaskItem.STATUS_RELEASED);
        saveReleasedMedicalCalculatorField(array, id, user, now, releasedMedicalCalculator);

        if (MedicalCalculator.COMPUTATIONAL.equals(formulaType + "")) {
            saveReleasedCalculationCalculator(user, medicalCalculatorData, releasedMedicalCalculator);
        } else if (MedicalCalculator.DECIDE.equals(formulaType + "")) {
            saveReleasedScoringCalculator(calculatorSore, user, now, releasedMedicalCalculator);
        }
        HistoryUtils.save(releasedMedicalCalculator.getId(), releasedMedicalCalculator.getFormulaName(), History.OPERATE_CORRECT, History.OPERATE_RESULT_SUCCESS);
        String sql = "select * from knowledge_sync_status where knowledge_id='" + releasedMedicalCalculator.getId() + "'";
        List<KnowledgeSyncStatus> knowledgeSyncStatusList = knowledgeSyncStatusService.lambdaQuery().eq(KnowledgeSyncStatus::getKnowledgeId, releasedMedicalCalculator.getId()).list();
        for (KnowledgeSyncStatus status1 : knowledgeSyncStatusList) {
            String updateSql = "update knowledge_sync_status set kind=2 where knowledge_id='" + status1.getKnowledgeId() + "'";
            knowledgeSyncStatusService.getBaseMapper().executeUpdate(updateSql);
        }
        try {
            Document template = Jsoup.connect(ApplicationContextUtil.getProperty("static-file.path")
                    + "calculator/export-template.html").maxBodySize(0).get();
            // 组装content内容;
            Map<String, Object> calculatorData = getReleaseCalculatorDataById(releasedMedicalCalculator.getId());
            template.body().child(0).text("let data = " + JSON.toJSONString(calculatorData));
            //后期可能会用到
            // template.body().child(0).text("let data = \"" + MD5Utils.aesEncryptToBytes(JSON.toJSONString(calculatorData)) + "\"");
            File formulaFile = new File(ApplicationContextUtil.BASE_DOWN_FORDER + "file/calculator/" + releasedMedicalCalculator.getId() + ".html");
            FileUtils.writeByteArrayToFile(formulaFile, StringEscapeUtils.unescapeHtml(template.html()).getBytes());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
        return releasedMedicalCalculator.getId();
    }

    private void saveReleasedScoringCalculator(String calculatorSore,
                                               String user,
                                               LocalDateTime now,
                                               ReleasedMedicalCalculator releasedMedicalCalculator) {
        JSONArray calculatorSoreArray = JSONArray.parseArray(calculatorSore);
        for (int i = 0; i < calculatorSoreArray.size(); i++) {
            JSONObject calculatorSoreData = calculatorSoreArray.getJSONObject(i);
            String scoreData = calculatorSoreData.getString("scoreData");
            ReleasedMedicalCalculatorScoreType type =
                    saveReleasedMedicalCalculatorScoreType(user, now, releasedMedicalCalculator, calculatorSoreData);
            JSONArray scoreArray = JSONArray.parseArray(scoreData);
            for (int j = 0; j < scoreArray.size(); j++) {
                JSONObject dataJson = scoreArray.getJSONObject(j);
                ReleasedMedicalCalculatorScore score =
                        saveReleasedMedicalCalculatorScore(user, type, dataJson);
                //构建评分列项
                saveReleasedMedicalCalculatorScoreItem(user, score, dataJson);
            }
            saveReleasedMedicalCalculatorResult(user, calculatorSoreData, type);
        }
    }

    private ReleasedMedicalCalculatorScoreType saveReleasedMedicalCalculatorScoreType(String user,
                                                                                      LocalDateTime now,
                                                                                      ReleasedMedicalCalculator releasedMedicalCalculator,
                                                                                      JSONObject calculatorSoreData) {
        String explain = calculatorSoreData.getString("explain");
        ReleasedMedicalCalculatorScoreType type = new ReleasedMedicalCalculatorScoreType();
        type.setCreatedBy(user);
        type.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        type.setUpdatedBy(user);
        type.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        type.setMedicalCalcId(releasedMedicalCalculator.getId());
        type.setExplain(explain);
        type = releasedMedicalCalculatorScoreTypeMapper.saveBean(type);

        return type;
    }

    private void saveReleasedMedicalCalculatorResult(String user,
                                                     JSONObject calculatorSoreData,
                                                     ReleasedMedicalCalculatorScoreType medicalCalculatorScoreType) {
        JSONArray sectionsArray = JSONArray.parseArray(calculatorSoreData.getString("sections"));
        for (int k = 0; k < sectionsArray.size(); k++) {
            JSONObject Json = sectionsArray.getJSONObject(k);
            String explanation = Json.getString("explanation");
            String result = Json.getString("result");
            ReleasedMedicalCalculatorResult result1 = new ReleasedMedicalCalculatorResult();
            result1.setResultDesc(explanation);
            result1.setResultDescFontColor(result);
            result1.setMedicalCalcCompScoreId(medicalCalculatorScoreType.getId());
            result1.setUpdatedBy(user);
            result1.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            result1.setUpdatedBy(user);
            result1.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            ReleasedMedicalCalculatorResult medicalCalculatorResult = releasedMedicalCalculatorResultMapper.saveBean(result1);
            saveReleasedMedicalCalculatorResultItem(Json, medicalCalculatorResult);
        }
    }

    private void saveReleasedMedicalCalculatorScoreItem(String user, ReleasedMedicalCalculatorScore calculatorScore, JSONObject dataJson) {
        String items = dataJson.getString("items");
        JSONArray itemsArray = JSONArray.parseArray(items);
        for (int n = 0; n < itemsArray.size(); n++) {
            JSONObject dataJson1 = itemsArray.getJSONObject(n);
            String itemId = dataJson1.getString("id");
            String describe = dataJson1.getString("describe");
            String score = dataJson1.getString("score");
            ReleasedMedicalCalculatorScoreItem medicalCalculatorScoreItem = new ReleasedMedicalCalculatorScoreItem();
            medicalCalculatorScoreItem.setSort(Integer.parseInt(itemId));
            medicalCalculatorScoreItem.setMedicalCalcScoreId(calculatorScore.getId());
            medicalCalculatorScoreItem.setName(describe);
            medicalCalculatorScoreItem.setScore(score);
            medicalCalculatorScoreItem.setCreatedBy(user);
            medicalCalculatorScoreItem.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorScoreItem.setUpdatedBy(user);
            medicalCalculatorScoreItem.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            releasedMedicalCalculatorScoreItemMapper.saveBean(medicalCalculatorScoreItem);
        }
    }

    private ReleasedMedicalCalculatorScore saveReleasedMedicalCalculatorScore(String user, ReleasedMedicalCalculatorScoreType medicalCalculatorScoreType, JSONObject dataJson) {
        ReleasedMedicalCalculatorScore meScore;
        String id = dataJson.getString("id");
        String name = dataJson.getString("name");
        String multiple = dataJson.getString("multiple");
        ReleasedMedicalCalculatorScore medicalCalculatorScore = new ReleasedMedicalCalculatorScore();
        medicalCalculatorScore.setSort(id);
        medicalCalculatorScore.setMedicalCalcScoreTypeId(medicalCalculatorScoreType.getId());
        medicalCalculatorScore.setName(name);
        medicalCalculatorScore.setType(multiple);
        medicalCalculatorScore.setCreatedBy(user);
        medicalCalculatorScore.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculatorScore.setUpdatedBy(user);
        medicalCalculatorScore.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        meScore = releasedMedicalCalculatorScoreMapper.saveBean(medicalCalculatorScore);
        return meScore;
    }

    private void saveReleasedMedicalCalculatorField(JSONArray array, String id, String user, LocalDateTime now, ReleasedMedicalCalculator releasedMedicalCalculator) {
        for (int i = 0; i < array.size(); i++) {
            JSONObject itemJson = array.getJSONObject(i);
            int kind = Integer.parseInt(itemJson.getString("kind"));
            String name = itemJson.getString("name");
            String field_id = itemJson.getString("field_id");
            ReleasedMedicalCalculatorField field = new ReleasedMedicalCalculatorField();
            field.setCreatedBy(user);
            field.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            field.setUpdatedBy(user);
            field.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            field.setKind(kind);
            field.setName(name);
            field.setMedicalCalcLibFieldId(field_id);
            field.setMedicalCalcId(releasedMedicalCalculator.getId());
            if (kind == MedicalCalculatorField.INPUT_BOX
                    || kind == MedicalCalculatorField.TEXT_FIELD
                    || kind == MedicalCalculatorField.DROP_DOWN
                    || kind == MedicalCalculatorField.EXPLAIN
                    || kind == MedicalCalculatorField.MORE_VALUE) {
                field.setProperty(itemJson.getString("property"));
            } else if (kind == MedicalCalculatorField.CASCADE) {
                String property = itemJson.getString("property");
                field.setProperty("[]".equals(property) ? "" : property);
            } else if (kind == MedicalCalculatorField.GROUP_BUTTON) {
                field.setName(itemJson.getString("name"));
            } else if (kind == MedicalCalculatorField.RICH_TEXT) {
                field.setProperty(moveImg(itemJson.getString("property"), id));
            }
            releasedMedicalCalculatorFieldMapper.saveBean(field);
        }
    }

    private ReleasedMedicalCalculator saveReleasedMedicalCalculator(JSONArray array, String id, String describe, int formulaType, String user, LocalDateTime now) {
        ReleasedMedicalCalculator medicalCalculator = new ReleasedMedicalCalculator();
        ReleasedMedicalCalculator calculator = releasedMedicalCalculatorMapper.selectById(id);
        medicalCalculator.setVersion(calculator.getVersion() + 1);
        deleteReleasedCalculator(id);
        medicalCalculator.setId(id);
        medicalCalculator.setFormulaName(array.getJSONObject(0).getString("property"));
        medicalCalculator.setCreatedBy(user);
        medicalCalculator.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculator.setUpdatedBy(user);
        medicalCalculator.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculator.setDescribe(describe);
        medicalCalculator.setFormulaType(formulaType);
        return releasedMedicalCalculatorMapper.saveBean(medicalCalculator);
    }

    /**
     * 保存未发布的医学计算器
     *
     * @param object         计算器json对象
     * @param taskItemId     计算器绑定的子任务ID
     * @param nameSuggestion
     * @return 保存后的医学计算器ID
     * @throws Exception 如果更新子任务时出现了异常
     */
    private String saveTempMedicalCalculator(JSONObject object, String taskItemId, String nameSuggestion) {
        JSONArray array = object.getJSONArray("items");
        String id = object.getString("id");
        String name = array.getJSONObject(0).getString("property");
        String describe = object.getString("describeContent");
        int formulaType = Integer.parseInt(object.getString("type"));
        String medicalCalculatorData = object.getString("medicalCalculatorData");
        String calculatorSore = object.getString("calculatorSore");
        String user = PMPHAppUtil.getCurrentUserEnName();
        LocalDateTime now = LocalDateTime.now();

        MedicalCalculator calculator =
                saveMedicalCalculator(id, name, describe, formulaType, user);
        saveMedicalCalculatorField(array, calculator.getId(), user, now);
        if (MedicalCalculator.COMPUTATIONAL.equals(formulaType + "")) {
            saveCalculationCalculator(user, medicalCalculatorData, calculator);
        } else if (MedicalCalculator.DECIDE.equals(formulaType + "")) {
            saveMedicalCalculatorResult(user, calculatorSore, calculator);
        }

        if (id == null) {
            saveHistory(calculator, History.OPERATE_NEW);
        }
        updateTaskItem(calculator, "save", "", taskItemId, nameSuggestion);

        return calculator.getId();
    }

    private void updateTaskItem(MedicalCalculator calculator,
                                String operation,
                                String rejectReason,
                                String taskItemId, String nameSuggestion) {
        TaskItem dbTaskItem = taskItemService.getById(taskItemId);
        dbTaskItem.setKnowledgeId(calculator.getId());
        int auditLevel = calculateAuditLevel(taskItemId);
        Integer modifiedStatus = KnowledgeEditUtil.auditStatus(calculator.getId(), auditLevel, operation);
        dbTaskItem.setStatus(modifiedStatus);
        dbTaskItem.setWordsCount(KnowledgeEditUtil.calculatorCountWords(calculator.getId()));
        dbTaskItem.setName(calculator.getFormulaName());
        dbTaskItem.setNameSuggestion(JSON.parseObject(nameSuggestion, NameSuggestion.class));
        if (TaskItem.STATUS_COMMIT.equals(modifiedStatus)) {
            dbTaskItem.setSubmitTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        }
        if (StringUtils.isNotBlank(rejectReason)) {
            dbTaskItem.setReject(rejectReason);
        }
        taskItemService.updateById(dbTaskItem);
    }

    @NotNull
    private MedicalCalculator saveMedicalCalculator(String id, String name, String describe, int formulaType,
                                                    String user) {
        MedicalCalculator calculator = medicalCalculatorMapper.selectById(id);
        if (Objects.isNull(calculator)) {
            calculator = new MedicalCalculator();
        } else {
            deleteById(id);
        }
        calculator.setId(id);
        calculator.setFormulaName(name);
        calculator.setVersion(0);
        calculator.setDescribe(describe);
        calculator.setFormulaType(formulaType);
        calculator.setCreatedBy(user);
        calculator.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        calculator.setUpdatedBy(user);
        calculator.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculatorMapper.saveBean(calculator);
        updateProperty(calculator, null, null);
        return calculator;
    }

    private void saveMedicalCalculatorField(JSONArray array, String id, String user, LocalDateTime now) {
        for (Object item : array) {
            JSONObject itemJson = (JSONObject) item;
            int kind = Integer.parseInt(itemJson.getString("kind"));
            String fieldId = itemJson.getString("field_id");
            String name = itemJson.getString("name");

            MedicalCalculatorField field = new MedicalCalculatorField();
            field.setCreatedBy(user);
            field.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            field.setUpdatedBy(user);
            field.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            field.setKind(kind);
            field.setName(name);
            field.setMedicalCalcLibFieldId(fieldId);
            field.setMedicalCalcId(id);
            if (kind == MedicalCalculatorField.INPUT_BOX
                    || kind == MedicalCalculatorField.TEXT_FIELD
                    || kind == MedicalCalculatorField.DROP_DOWN
                    || kind == MedicalCalculatorField.EXPLAIN
                    || kind == MedicalCalculatorField.MORE_VALUE) {
                field.setProperty(itemJson.getString("property"));
            } else if (kind == MedicalCalculatorField.CASCADE) {
                String property = itemJson.getString("property");
                field.setProperty("[]".equals(property) ? "" : property);
            } else if (kind == MedicalCalculatorField.GROUP_BUTTON) {
                field.setName(itemJson.getString("name"));
            } else if (kind == MedicalCalculatorField.RICH_TEXT) {
                field.setProperty(moveImg(itemJson.getString("property"), id));
            }
            medicalCalculatorFieldMapper.saveBean(field);
        }
    }

    /**
     * 根据子任务ID取得对应任务的审核级别
     *
     * @param taskItemId 子任务ID
     * @return 知识绑定的任务的审核级别
     * @throws Exception 如果一个医学计算器绑定了多个子任务
     * @throws Exception 如果医学计算器没有绑定任何子任务
     */
    @SuppressWarnings("unchecked")
    private int calculateAuditLevel(String taskItemId) {
        String sql = "select t.* from task as t " +
                " left join task_item ti on t.id = ti.task_id " +
                " where ti.id = '" + taskItemId + "'" +
                "  and t.status != " + Task.STATUS_FINISHED +
                "  and ti.deleted = " + TaskItem.NO_DELETED;
        List<Task> taskList = taskService.getBaseMapper().executeMultiSelect(sql);
        if (taskList.size() > 1) {
            throw new RuntimeException("一个子任务绑定了多个任务");
        } else if (taskList.size() == 1) {
            return taskList.get(0).getAuditLevel();
        } else {
            throw new RuntimeException("子任务没有绑定任何任务");
        }
    }

    private void saveCalculationCalculator(String username, String medicalCalculatorData, MedicalCalculator calculator) {
        JSONArray medicalCalculatorArray = JSONArray.parseArray(medicalCalculatorData);
        for (int i = 0; i < medicalCalculatorArray.size(); i++) {
            JSONObject calculatorData = medicalCalculatorArray.getJSONObject(i);
            JSONObject calculateData = calculatorData.getJSONObject("calculateData");

            MedicalCalculatorComputation computation = saveMedicalCalculatorComputation(username, calculator, calculatorData, calculateData);
            saveMedicalCalculatorComputationFormulator(calculateData, computation);
            saveMedicalCalculatorComputationItem(username, calculateData, computation);
            saveMedicalCalculatorResult(username, calculatorData, computation.getId());
        }
    }

    private void saveMedicalCalculatorResult(String username, JSONObject calculatorData, String id) {
        JSONArray sectionArray = JSONArray.parseArray(calculatorData.getString("sections"));
        for (int k = 0; k < sectionArray.size(); k++) {
            JSONObject section = sectionArray.getJSONObject(k);
            String explanation = section.getString("explanation");
            String result = section.getString("result");
            MedicalCalculatorResult result1 = new MedicalCalculatorResult();
            result1.setResultDesc(explanation);
            result1.setResultDescFontColor(result);
            result1.setMedicalCalcCompScoreId(id);
            result1.setUpdatedBy(username);
            result1.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            result1.setUpdatedBy(username);
            result1.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            MedicalCalculatorResult medicalCalculatorResult = medicalCalculatorResultMapper.saveBean(result1);
            saveMedicalCalculatorResultItem(section, medicalCalculatorResult.getId());
        }
    }

    private void saveMedicalCalculatorResultItem(JSONObject section, String id2) {
        String innerSections = section.getString("sections");
        JSONArray innerSectionArray = JSONArray.parseArray(innerSections);
        for (int j = 0; j < innerSectionArray.size(); j++) {
            JSONObject sectionJson = innerSectionArray.getJSONObject(j);
            Integer id = sectionJson.getInteger("id");
            String condition = sectionJson.getString("condition");
            int relation = sectionJson.getInteger("relation");
            String value = sectionJson.getString("value");
            MedicalCalculatorResultItem resultItem = new MedicalCalculatorResultItem();
            resultItem.setCondition(Integer.parseInt(condition));
            resultItem.setMedicalCalcResultId(id2);
            resultItem.setRelation(relation);
            resultItem.setValue(value);
            resultItem.setSort(id);
            medicalCalculatorResultItemMapper.saveBean(resultItem);
        }
    }

    private void saveMedicalCalculatorComputationItem(String username, JSONObject calculateData, MedicalCalculatorComputation computation1) {
        //构建构建医学计算器计算型-列项实体
        JSONArray formulaItemsArray = JSONArray.parseArray(calculateData.getString("formulaItems"));
        for (int j = 0; j < formulaItemsArray.size(); j++) {
            JSONObject formulaItemsJson = formulaItemsArray.getJSONObject(j);
            String item_id = formulaItemsJson.getString("item_id");
            String item_name = formulaItemsJson.getString("item_name");
            String item_unit = formulaItemsJson.getString("item_unit");
            MedicalCalculatorComputationItem item = new MedicalCalculatorComputationItem();
            item.setName(item_name);
            item.setCode(item_id);
            item.setUnit(item_unit);
            item.setMedicalCalcCompId(computation1.getId());
            item.setCreatedBy(username);
            item.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            item.setUpdatedBy(username);
            item.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorComputationItemMapper.saveBean(item);
        }
    }

    private void saveMedicalCalculatorComputationFormulator(JSONObject calculateData, MedicalCalculatorComputation computation1) {
        JSONArray formulaExpressionItemsArray = JSONArray.parseArray(calculateData.getString("formulaExpressionItems"));
        //构建构建医学计算器计算型-公式实体
        for (int j = 0; j < formulaExpressionItemsArray.size(); j++) {
            JSONObject formulaExpressionItemsJson = formulaExpressionItemsArray.getJSONObject(j);
            String item_expression = formulaExpressionItemsJson.getString("item_expression");
            String item_type = formulaExpressionItemsJson.getString("item_type");
            MedicalCalculatorComputationFormulator formulator = new MedicalCalculatorComputationFormulator();
            formulator.setFormulator(item_expression);
            formulator.setCondition(item_type);
            formulator.setMedicalCalcCompId(computation1.getId());
            medicalCalculatorComputationFormulatorMapper.saveBean(formulator);
        }
    }

    private MedicalCalculatorComputation saveMedicalCalculatorComputation(String username, MedicalCalculator calculator, JSONObject calculatorData, JSONObject calculateData) {
        String explain = calculatorData.getString("explain");
        String resultUnit = calculateData.getString("resultUnit");

        //构建医学计算器计算型实体 saveMedicalCalculatorComputation
        MedicalCalculatorComputation computation = new MedicalCalculatorComputation();
        computation.setUnit(resultUnit);
        computation.setGender(explain);
        computation.setMedicalCalcId(calculator.getId());
        computation.setCreatedBy(username);
        computation.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        computation.setUpdatedBy(username);
        computation.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        return medicalCalculatorComputationMapper.saveBean(computation);
    }

    private void saveReleasedCalculationCalculator(String username, String medicalCalculatorData, ReleasedMedicalCalculator releasedMedicalCalculator) {
        JSONArray medicalCalculatorArray = JSONArray.parseArray(medicalCalculatorData);
        for (int i = 0; i < medicalCalculatorArray.size(); i++) {
            JSONObject CalculatorData = medicalCalculatorArray.getJSONObject(i);
            String explain = CalculatorData.getString("explain");
            JSONObject Calculator = CalculatorData.getJSONObject("calculateData");
            String resultUnit = Calculator.getString("resultUnit");

            //构建医学计算器计算型实体
            ReleasedMedicalCalculatorComputation computation1 =
                    saveReleasedMedicalCalculatorComputation(username, releasedMedicalCalculator, explain, resultUnit);
            //构建构建医学计算器计算型-公式实体
            saveReleasedMedicalCalculatorComputationFormulator(Calculator, computation1);
            //构建构建医学计算器计算型-列项实体
            saveReleasedMedicalCalculatorComputationItem(username, Calculator, computation1);
            saveReleasedMedicalCalculatorResult(username, CalculatorData, computation1);
        }
    }

    private void saveReleasedMedicalCalculatorResult(String username,
                                                     JSONObject CalculatorData,
                                                     ReleasedMedicalCalculatorComputation computation1) {
        JSONArray sectionsArray = JSONArray.parseArray(CalculatorData.getString("sections"));
        for (int k = 0; k < sectionsArray.size(); k++) {
            JSONObject Json = sectionsArray.getJSONObject(k);
            String explanation = Json.getString("explanation");
            String result = Json.getString("result");
            ReleasedMedicalCalculatorResult calculatorResult = new ReleasedMedicalCalculatorResult();
            calculatorResult.setResultDesc(explanation);
            calculatorResult.setResultDescFontColor(result);
            calculatorResult.setMedicalCalcCompScoreId(computation1.getId());
            calculatorResult.setUpdatedBy(username);
            calculatorResult.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            calculatorResult.setUpdatedBy(username);
            calculatorResult.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            ReleasedMedicalCalculatorResult medicalCalculatorResult = releasedMedicalCalculatorResultMapper.saveBean(calculatorResult);
            saveReleasedMedicalCalculatorResultItem(Json, medicalCalculatorResult);
        }
    }

    private void saveReleasedMedicalCalculatorResultItem(JSONObject json, ReleasedMedicalCalculatorResult medicalCalculatorResult) {
        String sections = json.getString("sections");
        JSONArray sectionArray = JSONArray.parseArray(sections);
        for (int j = 0; j < sectionArray.size(); j++) {
            JSONObject sectionJson = sectionArray.getJSONObject(j);
            Integer id = sectionJson.getInteger("id");
            String condition = sectionJson.getString("condition");
            int relation = sectionJson.getInteger("relation");
            String value = sectionJson.getString("value");
            ReleasedMedicalCalculatorResultItem resultItem = new ReleasedMedicalCalculatorResultItem();
            resultItem.setCondition(Integer.parseInt(condition));
            resultItem.setMedicalCalcResultId(medicalCalculatorResult.getId());
            resultItem.setRelation(relation);
            resultItem.setValue(value);
            resultItem.setSort(id);
            releasedMedicalCalculatorResultItemMapper.saveBean(resultItem);
        }
    }

    private void saveReleasedMedicalCalculatorComputationItem(String username, JSONObject Calculator, ReleasedMedicalCalculatorComputation computation1) {
        JSONArray formulaItemsArray = JSONArray.parseArray(Calculator.getString("formulaItems"));
        for (int j = 0; j < formulaItemsArray.size(); j++) {
            JSONObject formulaItemsJson = formulaItemsArray.getJSONObject(j);
            String item_id = formulaItemsJson.getString("item_id");
            String item_name = formulaItemsJson.getString("item_name");
            String item_unit = formulaItemsJson.getString("item_unit");
            ReleasedMedicalCalculatorComputationItem item = new ReleasedMedicalCalculatorComputationItem();
            item.setName(item_name);
            item.setCode(item_id);
            item.setUnit(item_unit);
            item.setMedicalCalcCompId(computation1.getId());
            item.setCreatedBy(username);
            item.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            item.setUpdatedBy(username);
            item.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            releasedMedicalCalculatorComputationItemMapper.saveBean(item);
        }
    }

    private void saveReleasedMedicalCalculatorComputationFormulator(JSONObject Calculator, ReleasedMedicalCalculatorComputation computation1) {
        JSONArray formulaExpressionItemsArray = JSONArray.parseArray(Calculator.getString("formulaExpressionItems"));
        for (int j = 0; j < formulaExpressionItemsArray.size(); j++) {
            JSONObject formulaExpressionItemsJson = formulaExpressionItemsArray.getJSONObject(j);
            String item_expression = formulaExpressionItemsJson.getString("item_expression");
            String item_type = formulaExpressionItemsJson.getString("item_type");
            ReleasedMedicalCalculatorComputationFormulator computationFormulator = new ReleasedMedicalCalculatorComputationFormulator();
            computationFormulator.setFormulator(item_expression);
            computationFormulator.setCondition(item_type);
            computationFormulator.setMedicalCalcCompId(computation1.getId());
            releasedMedicalCalculatorComputationFormulatorMapper.saveBean(computationFormulator);
        }
    }

    private ReleasedMedicalCalculatorComputation saveReleasedMedicalCalculatorComputation(String username, ReleasedMedicalCalculator releasedMedicalCalculator, String explain, String resultUnit) {
        ReleasedMedicalCalculatorComputation computation = new ReleasedMedicalCalculatorComputation();
        computation.setUnit(resultUnit);
        computation.setGender(explain);
        computation.setMedicalCalcId(releasedMedicalCalculator.getId());
        computation.setCreatedBy(username);
        computation.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        computation.setUpdatedBy(username);
        computation.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        return releasedMedicalCalculatorComputationMapper.saveBean(computation);
    }

    private void saveHistory(MedicalCalculator medicalCalculator1, int operate) {
        History history = new History();
        history.setKnowledgeId(medicalCalculator1.getId());
        history.setKnowledgeName(medicalCalculator1.getFormulaName());
        history.setOperate(operate);
        history.setOresult(History.OPERATE_RESULT_SUCCESS);
        historyMapper.saveBean(history);
    }

    private void buildMedicalField(String username, MedicalCalculator medicalCalculator1, String kind, String name, String field_id, MedicalCalculatorField medicalCalculatorField) {
        medicalCalculatorField.setCreatedBy(username);
        medicalCalculatorField.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculatorField.setUpdatedBy(username);
        medicalCalculatorField.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculatorField.setKind(Integer.parseInt(kind));
        medicalCalculatorField.setName(name);
        medicalCalculatorField.setMedicalCalcLibFieldId(field_id);
        medicalCalculatorField.setMedicalCalcId(medicalCalculator1.getId());
    }

    /**
     * 公式保存时，修改图片存储路径/download/image/calculator/calculator.id/image.id
     */
    private void updateProperty(MedicalCalculator medicalCalculator, ReleasedMedicalCalculator releasedMedicalCalculator, Integer status) {
        String sql = "";
        if (status != null && status.equals(TaskItem.STATUS_RELEASED)) {
            releasedMedicalCalculator.setDescribe(moveImg(releasedMedicalCalculator.getDescribe(), releasedMedicalCalculator.getId()));
            sql = "update released_medical_calculator set `DESCRIBE` ='" + releasedMedicalCalculator.getDescribe() + "'" + " where id='" + releasedMedicalCalculator.getId() + "'";
            releasedMedicalCalculatorMapper.executeUpdate(sql);
        } else {
            medicalCalculator.setDescribe(moveImg(medicalCalculator.getDescribe(), medicalCalculator.getId()));
            sql = "update medical_calculator set `DESCRIBE` ='" + medicalCalculator.getDescribe() + "'" + " where id='" + medicalCalculator.getId() + "'";
            medicalCalculatorMapper.executeUpdate(sql);
        }


    }

    /**
     * 公式字段保存时，修改图片存储路径/download/image/calculator/calculator.id/image.id
     */
    private void updateMedicalCalculatorProperty(MedicalCalculator medicalCalculator, ReleasedMedicalCalculator releasedMedicalCalculator, String status) {
        if (Integer.parseInt(status) == TaskItem.STATUS_RELEASED) {
            List<ReleasedMedicalCalculatorField> releasedMedicalCalculatorFields = releasedMedicalCalculatorFieldMapper.selectBeansByWherePart(" medical_calc_id = '" + releasedMedicalCalculator.getId() + "'");
            for (ReleasedMedicalCalculatorField releasedMedicalCalculatorField : releasedMedicalCalculatorFields) {
                if (releasedMedicalCalculatorField.getKind() == MedicalCalculatorField.RICH_TEXT) {
                    releasedMedicalCalculatorField.setProperty(moveImg(releasedMedicalCalculatorField.getProperty(), releasedMedicalCalculatorField.getId()));
                    String sql = "update released_medical_calculator_field set `property` = '" + releasedMedicalCalculatorField.getProperty() + "'" + " where id='" + releasedMedicalCalculatorField.getId() + "'and kind = 3";
                    releasedMedicalCalculatorFieldMapper.executeUpdate(sql);
                }
            }
        } else {
            List<MedicalCalculatorField> medicalCalculatorFields = medicalCalculatorFieldMapper.selectBeansByWherePart(" medical_calc_id = '" + medicalCalculator.getId() + "'");
            for (MedicalCalculatorField medicalCalculatorField : medicalCalculatorFields) {
                if (medicalCalculatorField.getKind() == MedicalCalculatorField.RICH_TEXT) {
                    medicalCalculatorField.setProperty(moveImg(medicalCalculatorField.getProperty(), medicalCalculatorField.getId()));
                    String sql = "update medical_calculator_field set `property` = '" + medicalCalculatorField.getProperty() + "'" + " where id='" + medicalCalculatorField.getId() + "'and kind = 3";
                    medicalCalculatorFieldMapper.executeUpdate(sql);
                }
            }
        }
    }

    private String moveImg(String property, String medicalCalculatorId) {
        if (StringUtils.isBlank(property)) {
            return "";
        }
        Document doc = Jsoup.parse(property);
        // 循环遍历所有节点
        for (Element element : doc.body().getAllElements()) {
            if (element.tagName().equalsIgnoreCase("img")) {
                if (!element.attr("class").equals("rw_img bz")) {
                    if (!element.attr("class").equals("BZ")) {
                        element.attr("class", element.attr("class"));
                    } else {
                        element.attr("class", "rw_img bz");
                    }
                    String imgSrc = element.attr("src");
                    String substring = StringUtils.substringBefore(imgSrc, "/ymer");
                    if (StringUtils.isBlank(imgSrc)) {
                        continue;
                    }
                    String despic = ApplicationContextUtil.BASE_DOWN_FORDER + "image/calculator/" + medicalCalculatorId + "/";
                    String fileName = imgSrc.substring(imgSrc.lastIndexOf("/") + 1);
                    // 数据库里存储的路径
                    String imgUrl = "/ymer/action/file/showImage?filename=image/calculator/" + medicalCalculatorId + "/" + fileName;
                    // 如果图片路径包含http，则直接下载到目标路径
                    if (element.attr("src").startsWith("http")) {
                        if (imgSrc.contains("ymer")) {
                            URL url = null;
                            try {
                                url = new URL(imgSrc);
                                FileUtils.copyURLToFile(url, new File(despic + fileName));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            element.attr("src", imgUrl);
                            continue;
                        } else {
                            throw new RuntimeException(" 富文本包含网络图片, 请先通过附件上传");
                        }
                    } else if (imgSrc.contains("image/bz")) {
                        element.attr("src", imgSrc.replace(substring, ""));
                        continue;
                    }
                }
            }
        }
        return Jsoup.parse(doc.body().html()).body().html();
    }

    public Map<String, Object> getCalculatorDataById(String id) {
        MedicalCalculator medicalCalculator = medicalCalculatorMapper.selectById(id);
        Map<String, Object> map = medicalCalculatorData(medicalCalculator);
        return map;
    }

    private Map<String, Object> medicalCalculatorData(MedicalCalculator medicalCalculator) {
        Map<String, Object> resultMap = new HashMap<>();
        String calculatorId = medicalCalculator.getId();
        String sql = "select * from medical_calculator_field where medical_calc_id='" + calculatorId + "' order by kind ";
        List<MedicalCalculatorField> medicalCalculatorFields = medicalCalculatorFieldMapper.executeMultiSelect(sql);
        List<Map<String, Object>> fieldList = new ArrayList<>();

        for (MedicalCalculatorField field : medicalCalculatorFields) {
            Map<String, Object> fieldMap = new HashMap<>();
            if (field.getKind() == MedicalCalculatorField.GROUP_BUTTON) {
                fieldMap.put("name", field.getName());
                fieldMap.put("kind", field.getKind());
                fieldMap.put("ident", field.getIdent());
                fieldMap.put("field_id", field.getMedicalCalcLibFieldId());
            } else if (field.getKind() == MedicalCalculatorField.CASCADE) {
                List<MedicalCalculatorLibField> calculatorLibFields = medicalCalculatorLibFieldMapper.selectBeansByWherePart(" name= '" + field.getName() + "'");
                for (MedicalCalculatorLibField calculatorLibField : calculatorLibFields) {
                    if (calculatorLibField.getName().equals(field.getName())) {
                        fieldMap.put("name", field.getName());
                        fieldMap.put("kind", field.getKind());
                        fieldMap.put("property", field.getProperty());
                        fieldMap.put("ident", field.getIdent());
                        fieldMap.put("field_id", field.getMedicalCalcLibFieldId());
                        List<Map<String, Object>> resultList = getSubjectOptions(calculatorLibField.getTagId());
                        fieldMap.put("tagId", resultList);
                    }
                }
            } else {
                getField(field, fieldMap);
            }
            fieldList.add(fieldMap);
        }
        resultMap.put("fields", fieldList);
        resultMap.put("describeContent", medicalCalculator.getDescribe());
        resultMap.put("type", medicalCalculator.getFormulaType());
        List<Map<String, Object>> computationList = getMedicalCalculatorDataMap(calculatorId);
        resultMap.put("medicalCalculatorData", computationList);
        List<Map<String, Object>> calculatorSoreList = getCalculatorSoreMap(calculatorId);
        resultMap.put("calculatorSore", calculatorSoreList);
        return resultMap;
    }

    private List<Map<String, Object>> getMedicalCalculatorDataMap(String calculatorId) {
        String sql = "select * from medical_calculator_computation where MEDICAL_CALC_ID = '" + calculatorId + "'";
        List<MedicalCalculatorComputation> computations = medicalCalculatorComputationMapper.executeMultiSelect(sql);
        List<Map<String, Object>> computationList = new ArrayList<>();
        if (computations.size() <= 0) {
            return new ArrayList<>();
        }
        for (MedicalCalculatorComputation computation : computations) {
            Map<String, Object> MedicalCalculatorMap = new HashMap<>();
            CalculateData calculateData = getCalculateDataMap(computation.getId());
            MedicalCalculatorMap.put("calculateData", calculateData);
            List<Map<String, Object>> sections = getSections(computation.getId());
            MedicalCalculatorMap.put("sections", sections);
            MedicalCalculatorMap.put("explain", computation.getGender());
            computationList.add(MedicalCalculatorMap);
        }
        return computationList;
    }

    private List<Map<String, Object>> getCalculatorSoreMap(String calculatorId) {
        String sql = "select * from medical_calculator_score_type where medical_calc_id = '" + calculatorId + "'";
        List<MedicalCalculatorScoreType> scoreTypes = medicalCalculatorScoreTypeMapper.executeMultiSelect(sql);
        List<Map<String, Object>> computationList = new ArrayList<>();
        if (scoreTypes.size() <= 0) {
            return new ArrayList<>();
        }
        for (MedicalCalculatorScoreType scoreType : scoreTypes) {
            Map<String, Object> calculatorScoreMap = new HashMap<>();
            List<Map<String, Object>> scoreData = getScoreData(scoreType.getId());
            calculatorScoreMap.put("scoreData", scoreData);
            List<Map<String, Object>> sections = getSoreSections(scoreType.getId());
            calculatorScoreMap.put("sections", sections);
            calculatorScoreMap.put("explain", scoreType.getExplain());
            computationList.add(calculatorScoreMap);
        }
        return computationList;
    }

    private List<Map<String, Object>> getScoreData(String calculatorId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from medical_calculator_score where medical_calc_score_type_id = '" + calculatorId + "' order by sort";
        List<MedicalCalculatorScore> scores = medicalCalculatorScoreMapper.executeMultiSelect(sql);
        for (MedicalCalculatorScore score : scores) {
            Map<String, Object> scoreMap = new HashMap<>();
            scoreMap.put("id", score.getSort());
            List<Map<String, Object>> itemList = getScoreDataItemList(score.getId());
            scoreMap.put("items", itemList);
            scoreMap.put("multiple", score.getType().equals("true"));
            scoreMap.put("name", score.getName());
            resultList.add(scoreMap);
        }
        return resultList;
    }

    private List<Map<String, Object>> getScoreDataItemList(String id) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from medical_calculator_score_item where MEDICAL_CALC_SCORE_ID = '" + id + "' order by sort";
        List<MedicalCalculatorScoreItem> items = medicalCalculatorScoreItemMapper.executeMultiSelect(sql);
        for (MedicalCalculatorScoreItem item : items) {
            Map<String, Object> itemMap = new HashMap<>();
            itemMap.put("id", item.getSort());
            itemMap.put("score", item.getScore());
            itemMap.put("describe", item.getName());
            resultList.add(itemMap);
        }
        return resultList;
    }

    private CalculateData getCalculateDataMap(String calculatorId) {
        String sql = "select * from medical_calculator_computation where id = '" + calculatorId + "'";
        List<MedicalCalculatorComputation> computations = medicalCalculatorComputationMapper.executeMultiSelect(sql);
        if (computations.size() <= 0) {
            return new CalculateData();
        }
        CalculateData calculateData = new CalculateData();
        for (MedicalCalculatorComputation computation : computations) {
            String computationId = computation.getId();
            List<Map<String, Object>> formulaItems = getFormulaItems(computationId);
            calculateData.setFormulaItems(formulaItems);
            List<Map<String, Object>> formulaExpressionItems = getFormulaExpressionItems(computationId);
            calculateData.setFormulaExpressionItems(formulaExpressionItems);
            calculateData.setResultUnit(computation.getUnit());
        }
        return calculateData;
    }

    private List<Map<String, Object>> getFormulaItems(String computationId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from medical_calculator_computation_item where MEDICAL_CALC_COMP_ID = '" + computationId + "'";
        List<MedicalCalculatorComputationItem> items = medicalCalculatorComputationItemMapper.executeMultiSelect(sql);
        for (MedicalCalculatorComputationItem item : items) {
            Map<String, Object> itemMap = new LinkedHashMap<>();
            itemMap.put("item_id", item.getCode());
            itemMap.put("item_name", item.getName());
            itemMap.put("item_unit", item.getUnit());
            resultList.add(itemMap);
        }
        return resultList;
    }

    private List<Map<String, Object>> getFormulaExpressionItems(String computationId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from medical_calculator_computation_formulator where medical_calc_comp_id = '" + computationId + "'";
        List<MedicalCalculatorComputationFormulator> formulators = medicalCalculatorComputationFormulatorMapper.executeMultiSelect(sql);
        for (MedicalCalculatorComputationFormulator formulator : formulators) {
            Map<String, Object> formulatorMap = new HashMap<>();
            formulatorMap.put("item_expression", formulator.getFormulator());
            formulatorMap.put("item_type", formulator.getCondition());
            resultList.add(formulatorMap);
        }
        return resultList;
    }

    private List<Map<String, Object>> getSections(String calculatorId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from medical_calculator_result where medical_calc_comp_score_id = '" + calculatorId + "'";
        List<MedicalCalculatorResult> results = medicalCalculatorResultMapper.executeMultiSelect(sql);
        for (MedicalCalculatorResult result : results) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("explanation", result.getResultDesc());
            resultMap.put("id", result.getSort());
            resultMap.put("result", result.getResultDescFontColor());
            List<Map<String, Object>> sectionList = getSectionList(result.getId());
            resultMap.put("sections", sectionList);
            resultList.add(resultMap);
        }
        return resultList;
    }

    private List<Map<String, Object>> getSoreSections(String calculatorId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from medical_calculator_result where medical_calc_comp_score_id = '" + calculatorId + "'";
        List<MedicalCalculatorResult> results = medicalCalculatorResultMapper.executeMultiSelect(sql);
        for (MedicalCalculatorResult result : results) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("explanation", result.getResultDesc());
            resultMap.put("id", result.getSort());
            resultMap.put("result", result.getResultDescFontColor());
            List<Map<String, Object>> sectionList = getSectionList(result.getId());
            resultMap.put("sections", sectionList);
            resultList.add(resultMap);
        }
        return resultList;
    }


    private List<Map<String, Object>> getSectionList(String id) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from medical_calculator_result_item where medical_calc_result_id = '" + id + "'";
        List<MedicalCalculatorResultItem> items = medicalCalculatorResultItemMapper.executeMultiSelect(sql);
        for (MedicalCalculatorResultItem item : items) {
            Map<String, Object> itemMap = new HashMap<>();
            itemMap.put("condition", item.getCondition());
            itemMap.put("id", item.getSort());
            itemMap.put("relation", item.getRelation());
            itemMap.put("value", item.getValue());
            resultList.add(itemMap);
        }
        return resultList;
    }

    public boolean deleteById(String medicalCalcId) {
        boolean result = true;
        try {
            // 删除医学计算器计算型相关表
            delCalcComp(medicalCalcId);
            // 删除医学计算器评分型相关表
            delCalcScoreType(medicalCalcId);
            // 删除医学计算表
            medicalCalculatorFieldMapper.deleteBeansByWherePart(" medical_calc_id = '" + medicalCalcId + "'");
            medicalCalculatorMapper.deleteById(medicalCalcId);
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 删除医学计算器计算型相关表
     *
     * @param medicalCalcId 医学计算器表id
     */
    private void delCalcComp(String medicalCalcId) {
        // 根据医学计算表id查询医学计算型表id
        String compSql = "select id from medical_calculator_computation where medical_calc_id = '" + medicalCalcId + "'";
        List<MedicalCalculatorComputation> compList = medicalCalculatorComputationMapper.executeMultiSelect(compSql);
        // 医学计算器对应的计算型ID集合
        if (CollectionUtils.isNotEmpty(compList)) {
            String compIds = StringUtils.join(compList.stream().map(MedicalCalculatorComputation::getId).collect(Collectors.toList()), "','");
            // 删除计算型对应的选项表
            medicalCalculatorComputationItemMapper.deleteBeansByWherePart(" medical_calc_comp_id in ('" + compIds + "')");
            // 删除计算型对应的公式表
            medicalCalculatorComputationFormulatorMapper.deleteBeansByWherePart(" medical_calc_comp_id in ('" + compIds + "')");
        }
        for (MedicalCalculatorComputation computation : compList) {
            delCalcResult(computation.getId());
        }
        // 删除计算型表
        medicalCalculatorComputationMapper.deleteBeansByWherePart(" medical_calc_id = '" + medicalCalcId + "'");
    }

    /**
     * 删除医学计算器评分型相关表
     *
     * @param medicalCalcId 医学计算器表id
     */
    private void delCalcScoreType(String medicalCalcId) {
        // 根据医学计算表id查询医学评分型类型表id
        String scoreTypeSql = "select id from medical_calculator_score_type where medical_calc_id = '" + medicalCalcId + "'";
        List<MedicalCalculatorScoreType> scoreTypeList = medicalCalculatorScoreTypeMapper.executeMultiSelect(scoreTypeSql);
        // 医学计算器对应的评分型类型表ID集合
        if (CollectionUtils.isNotEmpty(scoreTypeList)) {
            String scoreTypeIds = StringUtils.join(scoreTypeList.stream().map(MedicalCalculatorScoreType::getId).collect(Collectors.toList()), "','");
            String scoreSql = "select id from medical_calculator_score where medical_calc_score_type_id in('" + scoreTypeIds + "')";
            //医学计算器-评分型题目表id
            List<MedicalCalculatorScore> scoreList = medicalCalculatorScoreMapper.executeMultiSelect(scoreSql);
            String scoreIds = StringUtils.join(scoreList.stream().map(MedicalCalculatorScore::getId).collect(Collectors.toList()), "','");
            // 删除评分型对应的选项表
            medicalCalculatorScoreItemMapper.deleteBeansByWherePart(" medical_calc_score_id in ('" + scoreIds + "')");
            //删除医学计算器-评分型题目表
            medicalCalculatorScoreMapper.deleteBeansByWherePart(" medical_calc_score_type_id in('" + scoreTypeIds + "')");
        }
        for (MedicalCalculatorScoreType scoreType : scoreTypeList) {
            delCalcResult(scoreType.getId());
        }
        // 删除评分型表
        medicalCalculatorScoreTypeMapper.deleteBeansByWherePart(" medical_calc_id = '" + medicalCalcId + "'");
    }

    /**
     * 删除医学计算器结果相关表
     *
     * @param medicalCalcId 医学计算器表id
     */
    private void delCalcResult(String medicalCalcId) {
        // 根据医学计算表id查询医学评分型表id
        String resultSql = "select id from medical_calculator_result where medical_calc_comp_score_id = '" + medicalCalcId + "'";
        List<MedicalCalculatorResult> resultList = medicalCalculatorResultMapper.executeMultiSelect(resultSql);
        // 医学计算器对应的结果ID集合
        if (CollectionUtils.isNotEmpty(resultList)) {
            String resultIds = StringUtils.join(resultList.stream().map(MedicalCalculatorResult::getId).collect(Collectors.toList()), "','");
            // 删除结果对应的选项表
            medicalCalculatorResultItemMapper.deleteBeansByWherePart(" medical_calc_result_id in ('" + resultIds + "')");
        }
        // 删除结果表
        medicalCalculatorResultMapper.deleteBeansByWherePart(" medical_calc_comp_score_id = '" + medicalCalcId + "'");
    }

    public List<MedicalCalculator> queryCalculatorList(int currentPage, int pageNum, String status, String platform, String name, String editor, String auditor, String type, String version, String updateTime, String subject) {
        String sql = "select c.*,mf.property from medical_calculator c LEFT JOIN medical_calculator_field mf on mf.medical_calc_id=c.id where  mf.kind=2 and c.id in (select ti.knowledge_id from task_item ti LEFT JOIN  task t on t.id=ti.task_id where ti.`status`=2 and t.system_type='calc')";
        if (StringUtils.isNotBlank(name)) {
            sql += " and c.formula_name like '%" + name + "%'";

        }
        if (StringUtils.isNotBlank(editor)) {
            sql += " and c.id in (select knowledge_id from task_item where editor = '" + editor + "' and status =" + TaskItem.STATUS_PASS + ")";
        }
        if (StringUtils.isNotBlank(auditor)) {
            sql += " and c.id in (select knowledge_id from task_item where (first_auditor = '" + auditor + "' or second_auditor = '" + auditor + "' or third_auditor = '" + auditor + "') and status = " + TaskItem.STATUS_PASS + ")";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and c.formula_type = '" + type + "'";
        }
        if (StringUtils.isNotBlank(version)) {
            sql += " and c.version= '" + version + "'";
        }
        if (StringUtils.isNotBlank(platform) && !"[]".equals(platform) && !"\"\"".equals(platform)) {
            sql += " and mf.property like '%" + platform + "%'";
        }
        if (StringUtils.isNotBlank(updateTime)) {
            String startTime = (updateTime.split(",")[0].trim());
            String endTime = (updateTime.split(",")[1].trim());
            sql += " and c.updated_time >= '" + startTime + "' and c.updated_time <= '" + endTime + "'";

        }
        if (StringUtils.isNotBlank(subject) && !"\"\"".equals(subject) && !"[]".equals(subject)) {
            String tagSql = "select medical_calc_id from medical_calculator_field where property in ('" + subject + "')";
            List<MedicalCalculatorField> medicalCalculatorFieldList = medicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(MedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";
            sql += " and c.id in" + tagId;
        }
        if (!status.equals("queryAll")) {
            sql += " order by updated_time desc,id limit " + currentPage * pageNum + " , " + pageNum;

        } else {
            sql += " order by updated_time desc";
        }
        List<MedicalCalculator> list = medicalCalculatorMapper.executeMultiSelect(sql);
        String calculatorIds = "('" + org.apache.commons.lang.StringUtils.join(list.stream().map(MedicalCalculator::getId).collect(Collectors.toList()), "','") + "')";
        String fieldSql = "select * from medical_calculator_field where medical_calc_id in " + calculatorIds;
        List<MedicalCalculatorField> fieldList = medicalCalculatorFieldMapper.executeMultiSelect(fieldSql);
        List<MedicalCalculatorField> fieldsList = new ArrayList<>();
        for (MedicalCalculatorField field : fieldList) {
            MedicalCalculatorField medicalField = new MedicalCalculatorField();
            List<Tag> tagList = null;
            if (field.getKind() == MedicalCalculatorField.CASCADE) {
                if (!"".equals(field.getProperty()) && !"[]".equals(field.getProperty()) && field.getProperty() != null) {
                    String tagIds = "(" + getTagId(field.getProperty()).replaceAll("\"", "'").replaceAll("\\[", "").replaceAll("]", "") + ")";
                    String tagSql = "select id,name,parent_id,tag_code,old_tag_code,enable,level from tag where id in " + tagIds;
                    tagList = tagMapper.executeMultiSelect(tagSql);
                }
                if (CollectionUtils.isNotEmpty(tagList)) {
                    medicalField.setProperty(tagList.stream().map(Tag::getName).collect(Collectors.joining(",")));
                } else {
                    medicalField.setProperty(field.getProperty());
                }
                medicalField.setId(field.getId());
                medicalField.setMedicalCalcId(field.getMedicalCalcId());
                medicalField.setName(field.getName());
                medicalField.setKind(field.getKind());
            }
            fieldsList.add(medicalField);
        }
        list.forEach(medicalCalculator -> {
            medicalCalculator.setMedicalCalculatorFieldList(fieldsList.stream().filter(field -> StringUtils.equals(field.getMedicalCalcId(), medicalCalculator.getId())).collect(Collectors.toList()));
        });
        return list;
    }

    public int getCalculatorTotalNum(String status, String platform, String name, String editor, String auditor, String type, String version, String updateTime, String subject) {
        String sql = "select c.*,mf.property from medical_calculator c LEFT JOIN medical_calculator_field mf on mf.medical_calc_id=c.id where  mf.kind=2 and c.id in (select ti.knowledge_id from task_item ti LEFT JOIN  task t on t.id=ti.task_id where ti.`status`=2 and t.system_type='calc')";
        if (StringUtils.isNotBlank(name)) {
            sql += " and c.formula_name like '%" + name + "%'";

        }
        if (StringUtils.isNotBlank(editor)) {
            sql += " and c.id in (select knowledge_id from task_item where editor = '" + editor + "' and status =" + TaskItem.STATUS_PASS + ")";
        }
        if (StringUtils.isNotBlank(auditor)) {
            sql += " and c.id in (select knowledge_id from task_item where (first_auditor = '" + auditor + "' or second_auditor = '" + auditor + "' or third_auditor = '" + auditor + "') and status =" + TaskItem.STATUS_PASS + ")";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and c.formula_type = '" + type + "'";
        }
        if (StringUtils.isNotBlank(version)) {
            sql += " and c.version= '" + version + "'";
        }
        if (StringUtils.isNotBlank(platform) && !"[]".equals(platform) && !"\"\"".equals(platform)) {
            sql += " and mf.property like '%" + platform + "%'";
        }
        if (StringUtils.isNotBlank(updateTime)) {
            String startTime = (updateTime.split(",")[0].trim());
            String endTime = (updateTime.split(",")[1].trim());
            sql += " and c.updated_time >= '" + startTime + "' and c.updated_time <= '" + endTime + "'";

        }
        if (StringUtils.isNotBlank(subject) && !"\"\"".equals(subject) && !"[]".equals(subject)) {
            String tagSql = "select medical_calc_id from medical_calculator_field where property in ('" + subject + "')";
            List<MedicalCalculatorField> medicalCalculatorFieldList = medicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(MedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";
            sql += " and c.id in" + tagId;
        }
        List<MedicalCalculator> list = medicalCalculatorMapper.executeMultiSelect(sql);
        return list.size();
    }

    public List<ReleasedMedicalCalculator> queryReleasedCalculatorList(int currentPage, int pageNum, String status, String platform, String name, String editor, String auditor, String type, String version, String updateTime, String subject, Integer isRevised) {
        String sql = "select c.*,mf.property  from released_medical_calculator c LEFT JOIN released_medical_calculator_field mf on mf.medical_calc_id=c.id where mf.kind =2 and c.deleted = 0";
        if (StringUtils.isNotBlank(name)) {
            sql += " and c.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(editor)) {
            sql += " and c.id in (select knowledge_id from task_item where editor = '" + editor + "' and status=" + TaskItem.STATUS_RELEASED + ")";
        }
        if (StringUtils.isNotBlank(auditor)) {
            sql += " and c.id in (select knowledge_id from task_item where (first_auditor = '" + auditor + "' or second_auditor = '" + auditor + "' or third_auditor = '" + auditor + "') and status=" + TaskItem.STATUS_RELEASED + ")";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and c.formula_type = '" + type + "'";
        }
        if (StringUtils.isNotBlank(version)) {
            sql += " and c.version = '" + version + "'";
        }
        if (isRevised != null) {
            // 修订
            if (isRevised == 2) {
                sql += " and c.id in (select knowledge_id from task_item where type = 2 and deleted=0 and status !=8)";
            }
            if (isRevised == 0) {
                sql += " and c.id not in (select knowledge_id from task_item where type = 2 and deleted=0 and status !=8) ";
            }
        }
        if (StringUtils.isNotBlank(platform) && !"[]".equals(platform) && !"\"\"".equals(platform)) {
            sql += " and mf.property like'%" + platform + "%'";
        }
        if (StringUtils.isNotBlank(updateTime)) {
            String startTime = (updateTime.split(",")[0].trim());
            String endTime = (updateTime.split(",")[1].trim());
            sql += " and c.updated_time >= '" + startTime + "' and c.updated_time <= '" + endTime + "'";

        }
        if (StringUtils.isNotBlank(subject) && !"\"\"".equals(subject) && !"[]".equals(subject)) {
            String tagSql = "select medical_calc_id from released_medical_calculator_field where property in ('" + subject + "')";
            List<ReleasedMedicalCalculatorField> medicalCalculatorFieldList = releasedMedicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(ReleasedMedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";
            sql += " and c.id in" + tagId;
        }
        sql += " order by updated_time desc ,id";
        if (pageNum != 0) {
            sql += " limit " + currentPage * pageNum + " , " + pageNum;
        }
        List<ReleasedMedicalCalculator> list = releasedMedicalCalculatorMapper.executeMultiSelect(sql);
        String calculatorIds = list.stream().map(ReleasedMedicalCalculator::getId).collect(Collectors.joining("','", "('", "')"));
        String fieldSql = "select * from released_medical_calculator_field where medical_calc_id in " + calculatorIds;
        List<ReleasedMedicalCalculatorField> fieldList = releasedMedicalCalculatorFieldMapper.executeMultiSelect(fieldSql);
        List<ReleasedMedicalCalculatorField> fieldsList = new ArrayList<>();
        for (ReleasedMedicalCalculatorField field : fieldList) {
            ReleasedMedicalCalculatorField releasedMedicalField = new ReleasedMedicalCalculatorField();
            List<Tag> tagList = null;
            if (field.getKind() == MedicalCalculatorField.CASCADE) {
                if (!"".equals(field.getProperty()) && !"[]".equals(field.getProperty()) && field.getProperty() != null) {
                    String tagIds = "(" + getTagId(field.getProperty()).replaceAll("\"", "'").replaceAll("\\[", "").replaceAll("]", "") + ")";
                    String tagSql = "select id,name,parent_id,tag_code,old_tag_code,enable,level from tag where id in " + tagIds;
                    tagList = tagMapper.executeMultiSelect(tagSql);
                }
                if (CollectionUtils.isNotEmpty(tagList)) {
                    releasedMedicalField.setProperty(tagList.stream().map(Tag::getName).collect(Collectors.joining(",")));
                } else {
                    releasedMedicalField.setProperty(field.getProperty());
                }
                releasedMedicalField.setId(field.getId());
                releasedMedicalField.setMedicalCalcId(field.getMedicalCalcId());
                releasedMedicalField.setName(field.getName());
                releasedMedicalField.setKind(field.getKind());
            }
            fieldsList.add(releasedMedicalField);
        }
        list.forEach(releasedMedicalCalculator -> {
            releasedMedicalCalculator.setMedicalCalculatorFieldList(fieldsList.stream().filter(field -> StringUtils.equals(field.getMedicalCalcId(), releasedMedicalCalculator.getId())).collect(Collectors.toList()));
        });
        return list;
    }


    public int getReleasedCalculatorTotalNum(String status, String platform, String name, String editor, String auditor, String type, String version, String updateTime, String subject,Integer isRevised) {
        String sql = "select c.*,mf.property  from released_medical_calculator c LEFT JOIN released_medical_calculator_field mf on mf.medical_calc_id=c.id where mf.kind =2 and c.deleted = 0";
        if (StringUtils.isNotBlank(name)) {
            sql += " and c.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(editor)) {
            sql += " and c.id in (select knowledge_id from task_item where editor = '" + editor + "' and status=" + TaskItem.STATUS_RELEASED + ")";
        }
        if (StringUtils.isNotBlank(auditor)) {
            sql += " and c.id in (select knowledge_id from task_item where (first_auditor = '" + auditor + "' or second_auditor = '" + auditor + "' or third_auditor = '" + auditor + "') and status=" + TaskItem.STATUS_RELEASED + ")";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and c.formula_type = '" + type + "'";
        }
        if (StringUtils.isNotBlank(version)) {
            sql += " and c.version = '" + version + "'";
        }
        if (StringUtils.isNotBlank(platform) && !"[]".equals(platform) && !"\"\"".equals(platform)) {
            sql += " and mf.property like '%" + platform + "%'";
        }
        if (isRevised != null) {
            if (isRevised == 2 && isRevised != null) {
                sql += " and c.id in (select knowledge_id from task_item where type = 2 and deleted=0 and status!=8)";
            }
            if (isRevised == 0 && isRevised != null) {
                sql += " and c.id not in (select knowledge_id from task_item where type = 2 and deleted=0 and status !=8) ";
            }
        }
        if (StringUtils.isNotBlank(updateTime)) {
            String startTime = (updateTime.split(",")[0].trim());
            String endTime = (updateTime.split(",")[1].trim());
            sql += " and c.updated_time >= '" + startTime + "' and c.updated_time <= '" + endTime + "'";
        }
        if (StringUtils.isNotBlank(subject) && !"\"\"".equals(subject) && !"[]".equals(subject)) {
            String tagSql = "select medical_calc_id from released_medical_calculator_field where property in ('" + subject + "')";
            List<ReleasedMedicalCalculatorField> medicalCalculatorFieldList = releasedMedicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(ReleasedMedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";
            sql += " and c.id in" + tagId;
        }
        List<ReleasedMedicalCalculator> list = releasedMedicalCalculatorMapper.executeMultiSelect(sql);
        return list.size();
    }

    public ReleasedMedicalCalculator CalculatorToRelease(String calculatorId, String userName) {
        if (hasUnConfirmedNameSuggestion(calculatorId)) {
            throw new RuntimeException("存在未确认的名称修改建议!");
        }
        if (StringUtils.isNotBlank(calculatorId)) {
            deleteReleasedCalculator(calculatorId);
        }
        //查询医学计算器,构建发布医学计算器实体
        MedicalCalculator medicalCalculator = medicalCalculatorMapper.selectById(calculatorId);
        ReleasedMedicalCalculator releasedMedicalCalculator = JSON.parseObject(JSON.toJSONString(medicalCalculator), ReleasedMedicalCalculator.class);
        releasedMedicalCalculator.setVersion((Objects.isNull(medicalCalculator.getVersion()) ? 0 : medicalCalculator.getVersion()) + 1);
        releasedMedicalCalculator.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        releasedMedicalCalculator.setDeleted(ReleasedMedicalCalculator.DELETED_NO);
        releasedMedicalCalculatorMapper.saveBean(releasedMedicalCalculator);
        //查询医学计算器字段表
        String fieldSql = "select * from medical_calculator_field where medical_calc_id='" + calculatorId + "'";
        List<MedicalCalculatorField> fieldList = medicalCalculatorFieldMapper.executeMultiSelect(fieldSql);
        for (MedicalCalculatorField medicalCalculatorField : fieldList) {
            //构建发布医学计算器字段表实体
            ReleasedMedicalCalculatorField releasedMedicalCalculatorField = JSON.parseObject(JSON.toJSONString(medicalCalculatorField), ReleasedMedicalCalculatorField.class);
            releasedMedicalCalculatorField.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            releasedMedicalCalculatorFieldMapper.saveBean(releasedMedicalCalculatorField);
        }
        //查询医学计算器公式类型表--计算型
        String computationSql = "select * from medical_calculator_computation where MEDICAL_CALC_ID='" + medicalCalculator.getId() + "'";
        List<MedicalCalculatorComputation> computationList = medicalCalculatorComputationMapper.executeMultiSelect(computationSql);
        if (computationList.size() > 0) {
            for (MedicalCalculatorComputation computation : computationList) {
                //构建发布医学计算器公式类型表--计算型实体
                ReleasedMedicalCalculatorComputation releaseComputation = JSON.parseObject(JSON.toJSONString(computation), ReleasedMedicalCalculatorComputation.class);
                releaseComputation.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
                releasedMedicalCalculatorComputationMapper.saveBean(releaseComputation);
            }
            //查询医学计算器公式
            String computationId = computationList.stream().map(MedicalCalculatorComputation::getId).collect(Collectors.joining("','", "('", "')"));
            String formulatorSql = "select * from medical_calculator_computation_formulator where medical_calc_comp_id in" + computationId;
            List<MedicalCalculatorComputationFormulator> formulatorList = medicalCalculatorComputationFormulatorMapper.executeMultiSelect(formulatorSql);
            for (MedicalCalculatorComputationFormulator formulator : formulatorList) {
                //构建发布医学计算器公式实体
                ReleasedMedicalCalculatorComputationFormulator releasedFormulator = JSON.parseObject(JSON.toJSONString(formulator), ReleasedMedicalCalculatorComputationFormulator.class);
                releasedMedicalCalculatorComputationFormulatorMapper.saveBean(releasedFormulator);
            }
            //查询医学计算器公式列项表
            String computationItemSql = "select * from medical_calculator_computation_item where medical_calc_comp_id in" + computationId;
            List<MedicalCalculatorComputationItem> itemList = medicalCalculatorComputationItemMapper.executeMultiSelect(computationItemSql);
            for (MedicalCalculatorComputationItem computationItem : itemList) {
                //构建发布医学计算器公式列项表实体
                ReleasedMedicalCalculatorComputationItem releasedComputationItem = JSON.parseObject(JSON.toJSONString(computationItem), ReleasedMedicalCalculatorComputationItem.class);
                releasedComputationItem.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
                releasedMedicalCalculatorComputationItemMapper.saveBean(releasedComputationItem);
            }
            //查询医学计算器计算型结果表
            String calculatorResultSql = "select * from medical_calculator_result where medical_calc_comp_score_id in" + computationId;
            List<MedicalCalculatorResult> calculatorResultList = medicalCalculatorResultMapper.executeMultiSelect(calculatorResultSql);
            for (MedicalCalculatorResult medicalCalculatorResult : calculatorResultList) {
                //构建发布医学计算器公式计算型结果表实体
                ReleasedMedicalCalculatorResult releasedMedicalCalculatorResult = JSON.parseObject(JSON.toJSONString(medicalCalculatorResult), ReleasedMedicalCalculatorResult.class);
                releasedMedicalCalculatorResult.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
                releasedMedicalCalculatorResultMapper.saveBean(releasedMedicalCalculatorResult);
            }
            //查询医学计算器结果列项表
            String resultId = calculatorResultList.stream().map(MedicalCalculatorResult::getId).collect(Collectors.joining("','", "('", "')"));
            String resultItemSql = "select * from medical_calculator_result_item where medical_calc_result_id in" + resultId;
            List<MedicalCalculatorResultItem> resultItemList = medicalCalculatorResultItemMapper.executeMultiSelect(resultItemSql);
            for (MedicalCalculatorResultItem resultItem : resultItemList) {
                //构建发布医学计算器结果列项表实体
                ReleasedMedicalCalculatorResultItem releasedResultItem = JSON.parseObject(JSON.toJSONString(resultItem), ReleasedMedicalCalculatorResultItem.class);
                releasedMedicalCalculatorResultItemMapper.saveBean(releasedResultItem);
            }
        }
        //查询评分型类型表
        String scoreTypeSql = "select * from medical_calculator_score_type where medical_calc_id='" + calculatorId + "'";
        List<MedicalCalculatorScoreType> scoreTypeList = medicalCalculatorScoreTypeMapper.executeMultiSelect(scoreTypeSql);
        for (MedicalCalculatorScoreType scoreType : scoreTypeList) {
            //构建发布评分型类型表
            ReleasedMedicalCalculatorScoreType releasedScoreType = JSON.parseObject(JSON.toJSONString(scoreType), ReleasedMedicalCalculatorScoreType.class);
            releasedScoreType.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            releasedMedicalCalculatorScoreTypeMapper.saveBean(releasedScoreType);
        }
        if (scoreTypeList.size() > 0) {
            //查询医学计算器-评分型题目表
            String scoreTypeId = scoreTypeList.stream().map(MedicalCalculatorScoreType::getId).collect(Collectors.joining("','", "('", "')"));
            String scoreSql = "select * from medical_calculator_score where medical_calc_score_type_id in" + scoreTypeId;
            List<MedicalCalculatorScore> scoreList = medicalCalculatorScoreMapper.executeMultiSelect(scoreSql);
            for (MedicalCalculatorScore score : scoreList) {
                //构建发布医学计算器-评分型题目表
                ReleasedMedicalCalculatorScore releasedScore = JSON.parseObject(JSON.toJSONString(score), ReleasedMedicalCalculatorScore.class);
                releasedMedicalCalculatorScoreMapper.saveBean(releasedScore);
            }

            //查询医学计算器公式类型表--评分型--选项表
            String scoreItemId = scoreList.stream().map(MedicalCalculatorScore::getId).collect(Collectors.joining("','", "('", "')"));
            String scoreItemSql = "select * from medical_calculator_score_item where MEDICAL_CALC_SCORE_ID in" + scoreItemId;
            List<MedicalCalculatorScoreItem> scoreItemList = medicalCalculatorScoreItemMapper.executeMultiSelect(scoreItemSql);
            for (MedicalCalculatorScoreItem scoreItem : scoreItemList) {
                //构建发布医学计算器公式类型--评分型--选项表
                ReleasedMedicalCalculatorScoreItem releasedScoreItem = JSON.parseObject(JSON.toJSONString(scoreItem), ReleasedMedicalCalculatorScoreItem.class);
                releasedMedicalCalculatorScoreItemMapper.saveBean(releasedScoreItem);
            }
            //查询医学计算器评分型结果表
            String calculatorResultSql = "select * from medical_calculator_result where medical_calc_comp_score_id in" + scoreTypeId;
            List<MedicalCalculatorResult> calculatorResultList = medicalCalculatorResultMapper.executeMultiSelect(calculatorResultSql);
            for (MedicalCalculatorResult medicalCalculatorResult : calculatorResultList) {
                //构建医学计算机评分型结果表
                ReleasedMedicalCalculatorResult releasedMedicalCalculatorResult = JSON.parseObject(JSON.toJSONString(medicalCalculatorResult), ReleasedMedicalCalculatorResult.class);
                releasedMedicalCalculatorResultMapper.saveBean(releasedMedicalCalculatorResult);
            }
            //查询医学计算器评分型结果列项表
            String resultId = calculatorResultList.stream().map(MedicalCalculatorResult::getId).collect(Collectors.joining("','", "('", "')"));
            String resultItemSql = "select * from medical_calculator_result_item where medical_calc_result_id in" + resultId;
            List<MedicalCalculatorResultItem> resultItemList = medicalCalculatorResultItemMapper.executeMultiSelect(resultItemSql);
            for (MedicalCalculatorResultItem resultItem : resultItemList) {
                //构建发布医学计算器评分型结果列项表
                ReleasedMedicalCalculatorResultItem releasedResultItem = JSON.parseObject(JSON.toJSONString(resultItem), ReleasedMedicalCalculatorResultItem.class);
                releasedMedicalCalculatorResultItemMapper.saveBean(releasedResultItem);
            }
        }
        String taskSql = "update task_item set status= " + TaskItem.STATUS_RELEASED
                + " where knowledge_id='" + releasedMedicalCalculator.getId() + "'";
        taskItemService.getBaseMapper().executeUpdate(taskSql);
        List<MedicalCalculatorLibField> libFields = medicalCalculatorLibFieldMapper.selectAll();
        List<PlatformKnowledgeLib> platformKnowledgeLibs = platformKnowledgeLibMapper.selectBeansByWherePart(" knowledge_lib_id='" + libFields.get(0).getKnowledgeLibId() + "'");
        for (PlatformKnowledgeLib platform : platformKnowledgeLibs) {
            KnowledgeSyncStatus knowledgeSyncStatus = new KnowledgeSyncStatus();
            knowledgeSyncStatus.setKnowledgeLibId(KnowledgeLib.CALCULATOR_LIB_ID);
            knowledgeSyncStatus.setKind(KnowledgeSyncStatus.FAILED_KIND_WAITING);
            knowledgeSyncStatus.setPlatformId(platform.getPlatformId());
            knowledgeSyncStatus.setVersion(releasedMedicalCalculator.getVersion());
            knowledgeSyncStatus.setKnowledgeId(releasedMedicalCalculator.getId());
            knowledgeLibService.saveKnowledgeSyncStatus(knowledgeSyncStatus);
        }
        History history = new History();
        history.setKnowledgeId(releasedMedicalCalculator.getId());
        history.setKnowledgeName(releasedMedicalCalculator.getFormulaName());
        history.setOperate(History.OPERATE_RELEASE);
        history.setOresult(History.OPERATE_RESULT_SUCCESS);
        historyMapper.saveBean(history);
        deleteById(calculatorId);
        //医学计算器发布后, 生成h5页面, 放到 file/calculator/ 文件夹下, 便于同步;
        try {
            Document template = Jsoup.connect(ApplicationContextUtil.getProperty("static-file.path") + "calculator/export-template.html").maxBodySize(0).get();
            // 组装content内容;
            Map<String, Object> calculatorData = getReleaseCalculatorDataById(calculatorId);
            template.body().child(0).text("let data = " + JSON.toJSONString(calculatorData));
            //后期可能用到
            //template.body().child(0).text("let data = \"" + MD5Utils.aesEncryptToBytes(JSON.toJSONString(calculatorData)) + "\"");
            File formulaFile = new File(ApplicationContextUtil.BASE_DOWN_FORDER + "file/calculator/" + calculatorId + ".html");
            FileUtils.writeByteArrayToFile(formulaFile, StringEscapeUtils.unescapeHtml(template.html()).getBytes());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
        return releasedMedicalCalculator;
    }


    public int SelectionCalculatorToRelease(List<String> medicalCalculatorIdList, String userName) {
        int nameSuggestionCount = 0;
        for (String medicalCalculatorId : medicalCalculatorIdList) {
            if (hasUnConfirmedNameSuggestion(medicalCalculatorId)) {
                nameSuggestionCount++;
                continue;
            }
            CalculatorToRelease(medicalCalculatorId, userName);
        }
        return nameSuggestionCount;
    }

    public void releasedCalculator2TempCalculator(String id, String userName) {
        //查询发布医学计算器,构建发布医学计算器实体
        ReleasedMedicalCalculator releasedMedicalCalculator = releasedMedicalCalculatorMapper.selectById(id);
        MedicalCalculator medicalCalculator = JSON.parseObject(JSON.toJSONString(releasedMedicalCalculator), MedicalCalculator.class);
        medicalCalculator.setVersion(releasedMedicalCalculator.getVersion());
        medicalCalculator.setUpdatedBy(userName);
        medicalCalculator.setCreatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculator.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
        medicalCalculatorMapper.saveBean(medicalCalculator);

        //查询发布医学计算器字段表
        String fieldSql = "select * from released_medical_calculator_field where medical_calc_id='" + id + "'";
        List<ReleasedMedicalCalculatorField> releasedFieldList = releasedMedicalCalculatorFieldMapper.executeMultiSelect(fieldSql);
        for (ReleasedMedicalCalculatorField releasedMedicalCalculatorField : releasedFieldList) {
            //构建医学计算器字段表实体
            MedicalCalculatorField medicalCalculatorField = JSON.parseObject(JSON.toJSONString(releasedMedicalCalculatorField), MedicalCalculatorField.class);
            medicalCalculatorField.setCreatedBy(userName);
            medicalCalculatorField.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorFieldMapper.saveBean(medicalCalculatorField);

        }
        //查询发布医学计算器公式类型表--计算型
        String computationSql = "select * from released_medical_calculator_computation where MEDICAL_CALC_ID='" + medicalCalculator.getId() + "'";
        List<ReleasedMedicalCalculatorComputation> releasedComputationList = releasedMedicalCalculatorComputationMapper.executeMultiSelect(computationSql);
        if (releasedComputationList.size() > 0) {
            for (ReleasedMedicalCalculatorComputation releasedComputation : releasedComputationList) {
                //构建医学计算器公式类型表--计算型实体
                MedicalCalculatorComputation computation = JSON.parseObject(JSON.toJSONString(releasedComputation), MedicalCalculatorComputation.class);
                computation.setUpdatedBy(userName);
                computation.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
                medicalCalculatorComputationMapper.saveBean(computation);

            }
            //查询医学计算器公式
            String releasedComputationId = releasedComputationList.stream().map(ReleasedMedicalCalculatorComputation::getId).collect(Collectors.joining("','", "('", "')"));
            String releasedFormulatorSql = "select * from released_medical_calculator_computation_formulator where medical_calc_comp_id in" + releasedComputationId;
            List<ReleasedMedicalCalculatorComputationFormulator> releasedFormulatorList = releasedMedicalCalculatorComputationFormulatorMapper.executeMultiSelect(releasedFormulatorSql);
            for (ReleasedMedicalCalculatorComputationFormulator releasedFormulator : releasedFormulatorList) {
                //构建发布医学计算器公式实体
                MedicalCalculatorComputationFormulator formulator = JSON.parseObject(JSON.toJSONString(releasedFormulator), MedicalCalculatorComputationFormulator.class);
                medicalCalculatorComputationFormulatorMapper.saveBean(formulator);

            }
            //查询医学计算器公式列项表
            String releasedComputationItemSql = "select * from released_medical_calculator_computation_item where medical_calc_comp_id in" + releasedComputationId;
            List<ReleasedMedicalCalculatorComputationItem> releasedItemList = releasedMedicalCalculatorComputationItemMapper.executeMultiSelect(releasedComputationItemSql);
            for (ReleasedMedicalCalculatorComputationItem releasedComputationItem : releasedItemList) {
                //构建发布医学计算器公式列项表实体
                MedicalCalculatorComputationItem computationItem = JSON.parseObject(JSON.toJSONString(releasedComputationItem), MedicalCalculatorComputationItem.class);
                computationItem.setUpdatedBy(userName);
                computationItem.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
                medicalCalculatorComputationItemMapper.saveBean(computationItem);

            }
            //查询医学计算器计算型结果表
            String releasedCalculatorResultSql = "select * from released_medical_calculator_result where medical_calc_comp_score_id in" + releasedComputationId;
            List<ReleasedMedicalCalculatorResult> releasedCalculatorResultList = releasedMedicalCalculatorResultMapper.executeMultiSelect(releasedCalculatorResultSql);
            for (ReleasedMedicalCalculatorResult releasedMedicalCalculatorResult : releasedCalculatorResultList) {
                //构建发布医学计算器公式计算型结果表实体
                MedicalCalculatorResult medicalCalculatorResult = JSON.parseObject(JSON.toJSONString(releasedMedicalCalculatorResult), MedicalCalculatorResult.class);
                medicalCalculatorResult.setUpdatedBy(userName);
                medicalCalculatorResult.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
                medicalCalculatorResultMapper.saveBean(medicalCalculatorResult);

            }
            //查询医学计算器结果列项表
            String releasedResultId = releasedCalculatorResultList.stream().map(ReleasedMedicalCalculatorResult::getId).collect(Collectors.joining("','", "('", "')"));
            String releasedResultItemSql = "select * from released_medical_calculator_result_item where medical_calc_result_id in" + releasedResultId;
            List<ReleasedMedicalCalculatorResultItem> releasedResultItemList = releasedMedicalCalculatorResultItemMapper.executeMultiSelect(releasedResultItemSql);
            for (ReleasedMedicalCalculatorResultItem releasedResultItem : releasedResultItemList) {
                //构建发布医学计算器结果列项表实体
                MedicalCalculatorResultItem resultItem = JSON.parseObject(JSON.toJSONString(releasedResultItem), MedicalCalculatorResultItem.class);
                medicalCalculatorResultItemMapper.saveBean(resultItem);

            }
        }
        //查询评分型类型表
        String releasedScoreTypeSql = "select * from released_medical_calculator_score_type where medical_calc_id='" + id + "'";
        List<ReleasedMedicalCalculatorScoreType> releasedScoreTypeList = releasedMedicalCalculatorScoreTypeMapper.executeMultiSelect(releasedScoreTypeSql);
        for (ReleasedMedicalCalculatorScoreType releasedScoreType : releasedScoreTypeList) {
            //构建发布评分型类型表
            MedicalCalculatorScoreType scoreType = JSON.parseObject(JSON.toJSONString(releasedScoreType), MedicalCalculatorScoreType.class);
            scoreType.setUpdatedBy(userName);
            scoreType.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorScoreTypeMapper.saveBean(scoreType);

        }
        if (releasedScoreTypeList.size() > 0) {
            //查询医学计算器-评分型题目表
            String releasedScoreTypeId = releasedScoreTypeList.stream().map(ReleasedMedicalCalculatorScoreType::getId).collect(Collectors.joining("','", "('", "')"));
            String scoreSql = "select * from released_medical_calculator_score where medical_calc_score_type_id in" + releasedScoreTypeId;
            List<ReleasedMedicalCalculatorScore> releasedScoreList = releasedMedicalCalculatorScoreMapper.executeMultiSelect(scoreSql);
            for (ReleasedMedicalCalculatorScore releasedScore : releasedScoreList) {
                //构建发布医学计算器-评分型题目表
                MedicalCalculatorScore score = JSON.parseObject(JSON.toJSONString(releasedScore), MedicalCalculatorScore.class);
                score.setUpdatedBy(userName);
                medicalCalculatorScoreMapper.saveBean(score);

            }

            //查询发布医学计算器公式类型表--评分型--选项表
            String releasedScoreItemId = releasedScoreList.stream().map(ReleasedMedicalCalculatorScore::getId).collect(Collectors.joining("','", "('", "')"));
            String releasedScoreItemSql = "select * from released_medical_calculator_score_item where MEDICAL_CALC_SCORE_ID in" + releasedScoreItemId;
            List<ReleasedMedicalCalculatorScoreItem> releasedScoreItemList = releasedMedicalCalculatorScoreItemMapper.executeMultiSelect(releasedScoreItemSql);
            for (ReleasedMedicalCalculatorScoreItem releasedScoreItem : releasedScoreItemList) {
                //构建医学计算器公式类型--评分型--选项表
                MedicalCalculatorScoreItem scoreItem = JSON.parseObject(JSON.toJSONString(releasedScoreItem), MedicalCalculatorScoreItem.class);
                scoreItem.setUpdatedBy(userName);
                medicalCalculatorScoreItemMapper.saveBean(scoreItem);

            }
            //查询医学计算器评分型结果表
            String releasedCalculatorResultSql = "select * from released_medical_calculator_result where medical_calc_comp_score_id in" + releasedScoreTypeId;
            List<ReleasedMedicalCalculatorResult> releaseCalculatorResultList = releasedMedicalCalculatorResultMapper.executeMultiSelect(releasedCalculatorResultSql);
            for (ReleasedMedicalCalculatorResult releasedMedicalCalculatorResult : releaseCalculatorResultList) {
                //构建医学计算机评分型结果表
                MedicalCalculatorResult medicalCalculatorResult = JSON.parseObject(JSON.toJSONString(releasedMedicalCalculatorResult), MedicalCalculatorResult.class);
                medicalCalculatorResult.setUpdatedBy(userName);
                medicalCalculatorResultMapper.saveBean(medicalCalculatorResult);

            }
            //查询医学计算器评分型结果列项表
            String releasedResultId = releaseCalculatorResultList.stream().map(ReleasedMedicalCalculatorResult::getId).collect(Collectors.joining("','", "('", "')"));
            String resultItemSql = "select * from released_medical_calculator_result_item where medical_calc_result_id in" + releasedResultId;
            List<ReleasedMedicalCalculatorResultItem> releasedResultItemList = releasedMedicalCalculatorResultItemMapper.executeMultiSelect(resultItemSql);
            for (ReleasedMedicalCalculatorResultItem releasedResultItem : releasedResultItemList) {
                //构建发布医学计算器评分型结果列项表
                MedicalCalculatorResultItem resultItem = JSON.parseObject(JSON.toJSONString(releasedResultItem), MedicalCalculatorResultItem.class);
                medicalCalculatorResultItemMapper.saveBean(resultItem);
            }
        }
    }


    public boolean deleteReleasedCalculator(String id) {
        boolean result = true;
        try {
            // 删除发布医学计算器计算型相关表
            delReleasedCalcComp(id);
            // 删除发布医学计算器评分型相关表
            delReleasedCalcScoreType(id);
            // 删除发布医学计算表
            releasedMedicalCalculatorFieldMapper.deleteBeansByWherePart(" medical_calc_id = '" + id + "'");
            releasedMedicalCalculatorMapper.deleteById(id);

        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        }
        return result;
    }

    public List<MedicalCalculator> queryCalculatorAuditList(int currentPage, int pageNum, String name, String subject, String editor, String platform, String updatedTime, String status) {
        String sql = "select c.*,mf.property  from medical_calculator c LEFT JOIN medical_calculator_field mf on mf.medical_calc_id=c.id where  mf.kind=2";
        if (StringUtils.isNotBlank(name)) {
            sql += " and  c.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(subject) && !"\"\"".equals(subject) && !"[]".equals(subject)) {
            String tagSql = "select medical_calc_id from medical_calculator_field where property in ('" + subject + "')";
            List<MedicalCalculatorField> medicalCalculatorFieldList = medicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(MedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";
            sql += " and c.id in" + tagId;
        }
        if (StringUtils.isNotBlank(platform) && !"[]".equals(platform) && !"\"\"".equals(platform)) {
            String platformId = platform.replaceAll("\\[\"", "").replaceAll("\"]", "");
            sql += " and mf.property like '%" + platformId + "%'";
        }
        if (StringUtils.isNotBlank(updatedTime)) {
            String startTime = (updatedTime.split(",")[0].trim());
            String endTime = (updatedTime.split(",")[1].trim());
            sql += " and c.created_time >= '" + startTime + "' and c.created_time <= '" + endTime + "'";

        }
        sql += " order by c.updated_time desc,id limit " + currentPage * pageNum + " , " + pageNum;
        List<MedicalCalculator> list = medicalCalculatorMapper.executeMultiSelect(sql);
        String calculatorIds = "('" + org.apache.commons.lang.StringUtils.join(list.stream().map(MedicalCalculator::getId).collect(Collectors.toList()), "','") + "')";
        String fieldSql = "select * from medical_calculator_field where medical_calc_id in " + calculatorIds;
        List<MedicalCalculatorField> fieldList = medicalCalculatorFieldMapper.executeMultiSelect(fieldSql);
        List<MedicalCalculatorField> fieldsList = new ArrayList<>();
        for (MedicalCalculatorField field : fieldList) {
            MedicalCalculatorField medicalField = new MedicalCalculatorField();
            List<Tag> tagList = null;
            if (field.getKind() == MedicalCalculatorField.CASCADE) {
                if (!"".equals(field.getProperty()) && !"[]".equals(field.getProperty()) && field.getProperty() != null) {
                    String tagIds = "(" + getTagId(field.getProperty()).replaceAll("\"", "'").replaceAll("\\[", "").replaceAll("]", "") + ")";
                    String tagSql = "select id,name,parent_id,tag_code,old_tag_code,enable,level from tag where id in " + tagIds;
                    tagList = tagMapper.executeMultiSelect(tagSql);
                }
                if (CollectionUtils.isNotEmpty(tagList)) {
                    medicalField.setProperty(tagList.stream().map(Tag::getName).collect(Collectors.joining(",")));
                    medicalField.setId(field.getId());
                    medicalField.setMedicalCalcId(field.getMedicalCalcId());
                    medicalField.setName(field.getName());
                    medicalField.setKind(field.getKind());
                }

            }
            fieldsList.add(medicalField);
        }
        list.forEach(medicalCalculator -> {
            medicalCalculator.setMedicalCalculatorFieldList(fieldsList.stream().filter(field -> StringUtils.equals(field.getMedicalCalcId(), medicalCalculator.getId())).collect(Collectors.toList()));
        });
        return list;
    }

    public int getCalculatorAuditTotalNum(String name, String subject, String editor, String platform, String updatedTime, String status) {
        String sql = "select c.*,mf.property  from medical_calculator c LEFT JOIN medical_calculator_field mf on mf.medical_calc_id=c.id where  mf.kind=2 and c.data_status != '" + MedicalCalculator.UN_COMMIT + "'";
        if (StringUtils.isNotBlank(name)) {
            sql += " and  c.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(subject) && !"\"\"".equals(subject) && !"[]".equals(subject)) {
            String tagSql = "select medical_calc_id from medical_calculator_field where property in ('" + subject + "')";
            List<MedicalCalculatorField> medicalCalculatorFieldList = medicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(MedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";
            sql += " and c.id in" + tagId;
        }
        if (StringUtils.isNotBlank(platform) && !"[]".equals(platform) && !"\"\"".equals(platform)) {
            String platformId = platform.replaceAll("\\[\"", "").replaceAll("\"]", "");
            sql += " and mf.property like '%" + platformId + "%'";
        }
        if (StringUtils.isNotBlank(updatedTime)) {
            String startTime = (updatedTime.split(",")[0].trim());
            String endTime = (updatedTime.split(",")[1].trim());
            sql += " and c.created_time >= '" + startTime + "' and c.created_time <= '" + endTime + "'";

        }
        sql += " order by c.updated_time desc";
        List<MedicalCalculator> list = medicalCalculatorMapper.executeMultiSelect(sql);
        return list.size();
    }

    public int saveRejectReason(String id, String reject) {
        String sql = "update medical_calculator set reject_reason = '" + reject + "', " +
                " data_status = '" + MedicalCalculator.REJECT + "'" + " where id = '" + id + "'";
        medicalCalculatorMapper.executeUpdate(sql);
        MedicalCalculator medicalCalculator = medicalCalculatorMapper.selectById(id);
        History history = new History();
        history.setKnowledgeId(id);
        history.setOperate(History.OPERATE_REJECT);
        history.setOresult(History.OPERATE_RESULT_SUCCESS);
        history.setKnowledgeName(medicalCalculator.getFormulaName());
        historyMapper.saveBean(history);
        return MedicalCalculator.SUCCESS;
    }

    private void delReleasedCalcComp(String medicalCalcId) {
        // 根据医学计算表id查询医学计算型表id
        String releasedCompSql = "select id from released_medical_calculator_computation where medical_calc_id = '" + medicalCalcId + "'";
        List<ReleasedMedicalCalculatorComputation> releasedCompList = releasedMedicalCalculatorComputationMapper.executeMultiSelect(releasedCompSql);
        // 医学计算器对应的计算型ID集合
        if (CollectionUtils.isNotEmpty(releasedCompList)) {
            String releasedCompIds = StringUtils.join(releasedCompList.stream().map(ReleasedMedicalCalculatorComputation::getId).collect(Collectors.toList()), "','");
            // 删除计算型对应的选项表
            releasedMedicalCalculatorComputationItemMapper.deleteBeansByWherePart(" medical_calc_comp_id in ('" + releasedCompIds + "')");
            // 删除计算型对应的公式表
            releasedMedicalCalculatorComputationFormulatorMapper.deleteBeansByWherePart(" medical_calc_comp_id in ('" + releasedCompIds + "')");
        }
        for (ReleasedMedicalCalculatorComputation releasedComputation : releasedCompList) {
            delReleasedCalcResult(releasedComputation.getId());
        }
        // 删除计算型表
        releasedMedicalCalculatorComputationMapper.deleteBeansByWherePart(" medical_calc_id = '" + medicalCalcId + "'");
    }

    private void delReleasedCalcScoreType(String medicalCalcId) {
        // 根据医学计算表id查询医学评分型类型表id
        String releasedScoreTypeSql = "select id from released_medical_calculator_score_type where medical_calc_id = '" + medicalCalcId + "'";
        List<ReleasedMedicalCalculatorScoreType> releasedScoreTypeList = releasedMedicalCalculatorScoreTypeMapper.executeMultiSelect(releasedScoreTypeSql);
        // 医学计算器对应的评分型类型表ID集合
        if (CollectionUtils.isNotEmpty(releasedScoreTypeList)) {
            String ReleasedScoreTypeIds = StringUtils.join(releasedScoreTypeList.stream().map(ReleasedMedicalCalculatorScoreType::getId).collect(Collectors.toList()), "','");
            String releasedScoreSql = "select id from released_medical_calculator_score where medical_calc_score_type_id in('" + ReleasedScoreTypeIds + "')";
            //医学计算器-评分型题目表id
            List<ReleasedMedicalCalculatorScore> releasedScoreList = releasedMedicalCalculatorScoreMapper.executeMultiSelect(releasedScoreSql);
            String releasedScoreIds = StringUtils.join(releasedScoreList.stream().map(ReleasedMedicalCalculatorScore::getId).collect(Collectors.toList()), "','");
            // 删除评分型对应的选项表
            releasedMedicalCalculatorScoreItemMapper.deleteBeansByWherePart(" medical_calc_score_id in ('" + releasedScoreIds + "')");
            //删除医学计算器-评分型题目表
            releasedMedicalCalculatorScoreMapper.deleteBeansByWherePart(" medical_calc_score_type_id in('" + ReleasedScoreTypeIds + "')");
        }
        for (ReleasedMedicalCalculatorScoreType releasedScoreType : releasedScoreTypeList) {
            delCalcResult(releasedScoreType.getId());
        }
        // 删除评分型表
        releasedMedicalCalculatorScoreTypeMapper.deleteBeansByWherePart(" medical_calc_id = '" + medicalCalcId + "'");
    }

    private void delReleasedCalcResult(String medicalCalcId) {
        // 根据医学计算表id查询医学评分型表id
        String releasedResultSql = "select id from released_medical_calculator_result where medical_calc_comp_score_id = '" + medicalCalcId + "'";
        List<ReleasedMedicalCalculatorResult> releasedResultList = releasedMedicalCalculatorResultMapper.executeMultiSelect(releasedResultSql);
        // 医学计算器对应的结果ID集合
        if (CollectionUtils.isNotEmpty(releasedResultList)) {
            String releasedResultIds = StringUtils.join(releasedResultList.stream().map(ReleasedMedicalCalculatorResult::getId).collect(Collectors.toList()), "','");
            // 删除结果对应的选项表
            releasedMedicalCalculatorResultItemMapper.deleteBeansByWherePart(" medical_calc_result_id in ('" + releasedResultIds + "')");
        }
        // 删除结果表
        releasedMedicalCalculatorResultMapper.deleteBeansByWherePart(" medical_calc_comp_score_id = '" + medicalCalcId + "'");
    }

    public boolean saveCalculatorField(String platform, String tableData) {
        // 已关联平台;
        List<PlatformKnowledgeLib> platformKnowledgeLibs = platformKnowledgeLibMapper.selectBeansByWherePart("knowledge_lib_id = '" + KnowledgeLib.CALCULATOR_LIB_ID + "'");
        List<String> platformIdListOri = platformKnowledgeLibs.stream().map(item -> item.getPlatformId()).collect(Collectors.toList());
        // 已关联tag;
        List<MedicalCalculatorLibField> libFields = medicalCalculatorLibFieldMapper.selectBeansByWherePart(" kind = " + MedicalCalculatorField.CASCADE);
        List<String> tagIdListOri = libFields.stream().map(MedicalCalculatorLibField::getTagId).collect(Collectors.toList());
        // 绑定平台保存逻辑
        String platformId = platform.replaceAll("\\[", "").replaceAll("]", "").replaceAll("\"", "");
        List<MedicalCalculatorLibField> fields = medicalCalculatorLibFieldMapper.selectAll();
        String id = fields.get(0).getKnowledgeLibId();
        platformKnowledgeLibMapper.deleteBeansByWherePart(" knowledge_lib_id ='" + id + "'");
        if (StringUtils.isNotEmpty(platformId)) {
            String[] platforms = platformId.split(",");
            for (int i = 0; i < platforms.length; i++) {
                String platform1 = platforms[i];
                PlatformKnowledgeLib platformKnowledgeLib = new PlatformKnowledgeLib();
                platformKnowledgeLib.setKnowledgeLibId(id);
                platformKnowledgeLib.setPlatformId(platform1);
                platformKnowledgeLib.setSystemType(KnowledgeSystem.CALCULATOR.value);
                platformKnowledgeLib.setAutosyncFlag(true);
                platformKnowledgeLibMapper.saveBean(platformKnowledgeLib);
            }
        }
        //获取数据库的数据
        String sql = "select * from medical_calculator_lib_field where ident=1";
        List<MedicalCalculatorLibField> medicalCalculatorLibFields = medicalCalculatorLibFieldMapper.executeMultiSelect(sql);
        List<MedicalCalculatorLibField> oldList = getOldList(medicalCalculatorLibFields);
        //获取页面数据
        List<MedicalCalculatorLibField> newList = newList(tableData);
        //获取新增的数据
        List<MedicalCalculatorLibField> addList = getAddList(newList);
        //获取修改的数据
        List<MedicalCalculatorLibField> updateList = getUpdateList(newList, oldList);
        //获取删除的数据
        List<MedicalCalculatorLibField> deleteList = getDeleteList(newList, oldList);
        List<MedicalCalculator> medicalCalculators = medicalCalculatorMapper.selectAll();
        List<ReleasedMedicalCalculator> releasedMedicalCalculators = releasedMedicalCalculatorMapper.selectAll();
        saveMedicalCalculator(addList, updateList, deleteList, medicalCalculators, releasedMedicalCalculators);
        // 开启新线程同步到关联平台;
        ExecutorServiceFactory.getInstance().submit(() -> syncCalculatorAndTag(platformIdListOri, tagIdListOri));
        return true;
    }

    private void syncCalculatorAndTag(List<String> platformIdListOri, List<String> tagIdListOri) {
        // 新的平台集合;
        List<PlatformKnowledgeLib> platformKnowledgeLibs = platformKnowledgeLibMapper.selectBeansByWherePart("knowledge_lib_id = '" + KnowledgeLib.CALCULATOR_LIB_ID + "'");
        List<String> platformIdList = platformKnowledgeLibs.stream().map(PlatformKnowledgeLib::getPlatformId).collect(Collectors.toList());
        // 新的tag集合;
        List<MedicalCalculatorLibField> libFields = medicalCalculatorLibFieldMapper.selectBeansByWherePart(" kind = " + MedicalCalculatorField.CASCADE);
        List<String> tagIdList = libFields.stream().map(MedicalCalculatorLibField::getTagId).collect(Collectors.toList());
        // 新增的平台关系;
        List<String> addPlatformList = platformIdList.stream().filter(item -> !platformIdListOri.contains(item)).collect(Collectors.toList());
        List<String> addTagIdList = tagIdList.stream().filter(item -> !tagIdListOri.contains(item)).collect(Collectors.toList());
        // 删除的关系;
        String deletePlatformList = platformIdListOri.stream().filter(item -> !platformIdList.contains(item)).collect(Collectors.joining("','", "('", "')"));
        List<ReleasedMedicalCalculator> releasedMedicalCalculators = releasedMedicalCalculatorMapper.selectAll();
        for (String platformId : addPlatformList) {
            // 新增平台, 同步所有tag;
            tagIdList.forEach(topTagId -> tagService.syncSubTagByTopTagId(platformId, topTagId));
            // 已发布计算器, 添加到待同步表;
            for (ReleasedMedicalCalculator releasedMedicalCalculator : releasedMedicalCalculators) {
                KnowledgeSyncStatus knowledgeSyncStatus = new KnowledgeSyncStatus();
                knowledgeSyncStatus.setKnowledgeLibId(KnowledgeLib.CALCULATOR_LIB_ID);
                knowledgeSyncStatus.setKind(KnowledgeSyncStatus.FAILED_KIND_WAITING);
                knowledgeSyncStatus.setPlatformId(platformId);
                knowledgeSyncStatus.setVersion(releasedMedicalCalculator.getVersion());
                knowledgeSyncStatus.setKnowledgeId(releasedMedicalCalculator.getId());
                knowledgeSyncStatusService.save(knowledgeSyncStatus);
            }
        }
        // 原有平台, 本次没改变, 同步新增tag;
        for (String platformId : platformIdListOri.stream().filter(platformIdList::contains).collect(Collectors.toList())) {
            addTagIdList.forEach(topTagId -> tagService.syncSubTagByTopTagId(platformId, topTagId));
        }
        // 删除的关系;
        knowledgeSyncStatusService.getBaseMapper().deleteBeansByWherePart(
                " knowledge_lib_id = '" + KnowledgeLib.CALCULATOR_LIB_ID + "' " +
                        " and platform_id in " + deletePlatformList);
        // 同步计算器库结构(按照知识库格式);
        KnowledgeLib knowledgeLib = getCalculatorLibAsKnowledgeLib();
        for (String platformId : platformIdList) {
            rocketMQProducerService.sendKnowledgeLib(platformId, knowledgeLib);
        }
    }

    private KnowledgeLib getCalculatorLibAsKnowledgeLib() {
        KnowledgeLib knowledgeLib = new KnowledgeLib();
        knowledgeLib.setId(KnowledgeLib.CALCULATOR_LIB_ID);
        knowledgeLib.setName(MedicalCalculator.CALCULATOR_LIB_NAME);
        knowledgeLib.setFieldList(new ArrayList<>());
        List<MedicalCalculatorLibField> medicalCalculatorLibFields = medicalCalculatorLibFieldMapper.selectAll();
        for (MedicalCalculatorLibField medicalCalculatorLibField : medicalCalculatorLibFields) {
            KnowledgeLibField knowledgeLibField = new KnowledgeLibField();
            knowledgeLibField.setId(medicalCalculatorLibField.getId());
            knowledgeLibField.setName(medicalCalculatorLibField.getName());
            if (medicalCalculatorLibField.getKind() == MedicalCalculatorField.CASCADE) {
                knowledgeLibField.setKind(KnowledgeLibField.FIELD_KIND_REFERENCE);
                knowledgeLibField.setKindValue(medicalCalculatorLibField.getTagId());
            } else if (medicalCalculatorLibField.getKind() == MedicalCalculatorField.INPUT_BOX) {
                knowledgeLibField.setKind(KnowledgeLibField.FIELD_KIND_STRINGTEXT);
            } else if (medicalCalculatorLibField.getKind() == MedicalCalculatorField.DROP_DOWN) {
                knowledgeLibField.setKind(KnowledgeLibField.FIELD_KIND_ASSOCIATE_PLATFORM);
            } else if (medicalCalculatorLibField.getKind() == MedicalCalculatorField.RICH_TEXT) {
                knowledgeLibField.setKind(KnowledgeLibField.FIELD_KIND_RICHEDITOR);
            } else if (medicalCalculatorLibField.getKind() == MedicalCalculatorField.TEXT_FIELD) {
                knowledgeLibField.setKind(KnowledgeLibField.FIELD_KIND_TEXTAREA);
            } else {
                knowledgeLibField.setKind(KnowledgeLibField.FIELD_KIND_STRINGTEXT);
            }
            knowledgeLibField.setKnowledgeLibId(knowledgeLib.getId());
            knowledgeLib.getFieldList().add(knowledgeLibField);
        }
        // 添加content内容字段;
        KnowledgeLibField knowledgeLibField = new KnowledgeLibField();
        knowledgeLibField.setId(MedicalCalculator.CALCULATOR_LIB_FIELD_ID_CONTENT);
        knowledgeLibField.setName(MedicalCalculator.CALCULATOR_LIB_FIELD_NAME_CONTENT);
        knowledgeLibField.setKind(KnowledgeLibField.CALCULATOR_FIELD_KIND_H5);
        knowledgeLibField.setKnowledgeLibId(knowledgeLib.getId());
        knowledgeLib.getFieldList().add(knowledgeLibField);
        return knowledgeLib;
    }

    public List<ReleasedMedicalCalculator> querySyncCalculatorList(int currentPage, int pageNum, String name, String subject, String platform, String type, String createTime, String syncStatus, String bindingPlatform) {
        String sql = "select c.*,mf.property,kss.kind as syncStatus, kss.operated_time as operatedTime from released_medical_calculator c " +
                " LEFT JOIN released_medical_calculator_field mf on mf.medical_calc_id=c.id " +
                " left join knowledge_sync_status kss on kss.knowledge_id = c.id and kss.platform_id = '" + bindingPlatform + "' " +
                " where mf.kind = 2 ";
        if (StringUtils.isNotBlank(name)) {
            sql += " and  c.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(subject) && !"\"\"".equals(subject) && !"[]".equals(subject)) {

            sql += " and c.id in (select medical_calc_id from released_medical_calculator_field where property in ('" + subject + "'))";
        }
        if (StringUtils.isNotBlank(platform)) {
            sql += " and mf.property like '%" + platform + "%'";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and  c.formula_type = '" + type + "'";
        }
        if (StringUtils.isNotBlank(createTime)) {
            String startTime = (createTime.split(",")[0].trim());
            String endTime = (createTime.split(",")[1].trim());
            sql += " and kss.operated_time >= '" + startTime + "' and kss.operated_time <= '" + endTime + "'";
        }
        if (StringUtils.isNotBlank(syncStatus)) {
            sql += " and kss.kind = " + syncStatus;
        }
        sql += " order by kss.operated_time desc,id limit " + currentPage * pageNum + " , " + pageNum;
        List<ReleasedMedicalCalculator> list = releasedMedicalCalculatorMapper.executeMultiSelect(sql);
        String calculatorIds = list.stream().map(ReleasedMedicalCalculator::getId).collect(Collectors.joining("','", "('", "')"));
        String fieldSql = "select * from released_medical_calculator_field where medical_calc_id in " + calculatorIds;
        List<ReleasedMedicalCalculatorField> fieldList = releasedMedicalCalculatorFieldMapper.executeMultiSelect(fieldSql);
        List<ReleasedMedicalCalculatorField> fieldsList = new ArrayList<>();
        for (ReleasedMedicalCalculatorField field : fieldList) {
            ReleasedMedicalCalculatorField releasedMedicalField = new ReleasedMedicalCalculatorField();
            List<Tag> tagList = null;
            if (field.getKind() == MedicalCalculatorField.CASCADE) {
                if (!"".equals(field.getProperty()) && !"[]".equals(field.getProperty()) && field.getProperty() != null) {
                    String tagIds = "(" + getTagId(field.getProperty()).replaceAll("\"", "'").replaceAll("\\[", "").replaceAll("]", "") + ")";
                    String tagSql = "select id,name,parent_id,tag_code,old_tag_code,enable,level from tag where id in " + tagIds;
                    tagList = tagMapper.executeMultiSelect(tagSql);
                }
                if (CollectionUtils.isNotEmpty(tagList)) {
                    releasedMedicalField.setProperty(tagList.stream().map(Tag::getName).collect(Collectors.joining(",")));
                } else {
                    releasedMedicalField.setProperty(field.getProperty());
                }
                releasedMedicalField.setId(field.getId());
                releasedMedicalField.setMedicalCalcId(field.getMedicalCalcId());
                releasedMedicalField.setName(field.getName());
                releasedMedicalField.setKind(field.getKind());
            }
            fieldsList.add(releasedMedicalField);
        }
        list.forEach(releasedMedicalCalculator -> {
            releasedMedicalCalculator.setMedicalCalculatorFieldList(fieldsList.stream().filter(field -> StringUtils.equals(field.getMedicalCalcId(), releasedMedicalCalculator.getId())).collect(Collectors.toList()));
        });
        return list;
    }


    public int getSyncCalculatorTotalNum(String name, String subject, String platform, String type, String createTime, String syncStatus, String bindingPlatform) {
        String sql = "select c.id  from released_medical_calculator c LEFT JOIN released_medical_calculator_field mf on mf.medical_calc_id=c.id where mf.kind =2";
        if (StringUtils.isNotBlank(name)) {
            sql += " and  c.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(subject) && !"\"\"".equals(subject) && !"[]".equals(subject)) {
            String tagSql = "select medical_calc_id from released_medical_calculator_field where property in ('" + subject + "')";
            List<ReleasedMedicalCalculatorField> medicalCalculatorFieldList = releasedMedicalCalculatorFieldMapper.executeMultiSelect(tagSql);
            String tagId = "('" + org.apache.commons.lang.StringUtils.join(medicalCalculatorFieldList.stream().map(ReleasedMedicalCalculatorField::getMedicalCalcId).collect(Collectors.toList()), "','") + "')";
            sql += " and c.id in" + tagId;
        }
        if (StringUtils.isNotBlank(platform) && !"[]".equals(platform) && !"\"\"".equals(platform)) {
            String platformId = platform.replaceAll("\\[\"", "").replaceAll("\"]", "");
            sql += " and mf.property like '%" + platformId + "%'";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and  c.formula_type = '" + type + "'";
        }
        if (StringUtils.isNotBlank(createTime)) {
            String startTime = (createTime.split(",")[0].trim());
            String endTime = (createTime.split(",")[1].trim());
            sql += " and c.id in (select knowledge_id from knowledge_sync_status where platform_id = '" + bindingPlatform + "' " +
                    " and operated_time >= '" + startTime + "' and operated_time <= '" + endTime + "')";
        }
        if (StringUtils.isNotBlank(syncStatus)) {
            sql += " and c.id in (select knowledge_id from knowledge_sync_status where platform_id = '" + bindingPlatform + "' and kind = " + syncStatus + ")";
        }
        List<ReleasedMedicalCalculator> list = releasedMedicalCalculatorMapper.executeMultiSelect(sql);
        return list.size();
    }

    public List<KnowledgeSyncStatus> queryKnowledgeSyncStatusList(int currentPage, int pageNum, String name, String kind, String platformId, String operatedTime) {
        List<MedicalCalculatorLibField> libFields = medicalCalculatorLibFieldMapper.selectAll();
        String knowledgeLibId = libFields.get(0).getKnowledgeLibId();
        String sql = " select ksf.*,mc.formula_name AS knowledge_name from knowledge_sync_status ksf LEFT JOIN released_medical_calculator mc on ksf.knowledge_id=mc.id where knowledge_lib_id='" + knowledgeLibId + "'";
        if (StringUtils.isNotBlank(name)) {
            sql += " and mc.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(kind)) {
            sql += " and ksf.kind=" + kind + "";
        } else {
            sql += " and ksf.kind < 2";
        }
        if (StringUtils.isNotBlank(platformId)) {
            sql += " and ksf.platform_id='" + platformId + "'";
        }
        if (StringUtils.isNotBlank(operatedTime)) {
            String startTime = (operatedTime.split(",")[0].trim());
            String endTime = (operatedTime.split(",")[1].trim());
            sql += " and ksf.operated_time >= '" + startTime + "' and ksf.operated_time <= '" + endTime + "'";
        }
        sql += " order by ksf.operated_time desc,id limit " + currentPage * pageNum + " , " + pageNum;
        List<KnowledgeSyncStatus> list = knowledgeSyncStatusService.getBaseMapper().executeMultiSelect(sql);
        for (KnowledgeSyncStatus knowledgeSyncFailed : list) {
            String platformSql = "select * from platform where id in ('" + knowledgeSyncFailed.getPlatformId() + "')";
            List<Platform> platformList = platformService.getBaseMapper().executeMultiSelect(platformSql);
            if (CollectionUtils.isNotEmpty(platformList)) {
                knowledgeSyncFailed.setPlatformName(platformList.stream().map(Platform::getName).collect(Collectors.joining(",")));
            }
        }
        return list;
    }

    public int getKnowledgeSyncStatusTotalNum(String name, String kind, String platformId, String operatedTime) {
        List<MedicalCalculatorLibField> libFields = medicalCalculatorLibFieldMapper.selectAll();
        String knowledgeLibId = libFields.get(0).getKnowledgeLibId();
        String sql = " select ksf.*,mc.formula_name AS knowledge_name from knowledge_sync_status ksf LEFT JOIN released_medical_calculator mc on ksf.knowledge_id=mc.id where knowledge_lib_id='" + knowledgeLibId + "'";
        if (StringUtils.isNotBlank(name)) {
            sql += " and mc.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(kind)) {
            sql += " and ksf.kind=" + kind;
        } else {
            sql += " and ksf.kind < 2";
        }
        if (StringUtils.isNotBlank(platformId)) {
            sql += " and ksf.platform_id='" + platformId + "'";
        }
        if (StringUtils.isNotBlank(operatedTime)) {
            String startTime = (operatedTime.split(",")[0].trim());
            String endTime = (operatedTime.split(",")[1].trim());
            sql += " and ksf.operated_time >= '" + startTime + "' and ksf.operated_time <= '" + endTime + "'";
        }
        List<KnowledgeSyncStatus> list = knowledgeSyncStatusService.getBaseMapper().executeMultiSelect(sql);
        return list.size();
    }

    private void saveMedicalCalculator(List<MedicalCalculatorLibField> addList, List<MedicalCalculatorLibField> updateList, List<MedicalCalculatorLibField> deleteList, List<MedicalCalculator> medicalCalculators, List<ReleasedMedicalCalculator> releasedMedicalCalculators) {
        for (MedicalCalculatorLibField medicalCalculatorLibField : addList) {
            medicalCalculatorLibField.setKind(medicalCalculatorLibField.getKind());
            medicalCalculatorLibField.setKnowledgeLibId(medicalCalculatorLibField.getKnowledgeLibId());
            medicalCalculatorLibField.setIdent(medicalCalculatorLibField.getIdent());
            medicalCalculatorLibField.setName(medicalCalculatorLibField.getName());
            medicalCalculatorLibField.setTagId(medicalCalculatorLibField.getTagId());
            medicalCalculatorLibField.setCreatedBy(PMPHAppUtil.getCurrentUserEnName());
            medicalCalculatorLibField.setUpdatedBy(PMPHAppUtil.getCurrentUserEnName());
            medicalCalculatorLibField.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorLibField.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorLibFieldMapper.saveBean(medicalCalculatorLibField);
        }
        for (MedicalCalculator medicalCalculator : medicalCalculators) {
            for (MedicalCalculatorLibField calculatorLibField : addList) {
                MedicalCalculatorField medicalCalculatorField = new MedicalCalculatorField();
                medicalCalculatorField.setMedicalCalcLibFieldId(calculatorLibField.getId());
                medicalCalculatorField.setKind(calculatorLibField.getKind());
                medicalCalculatorField.setName(calculatorLibField.getName());
                medicalCalculatorField.setIdent(calculatorLibField.getIdent());
                medicalCalculatorField.setMedicalCalcId(medicalCalculator.getId());
                medicalCalculatorField.setCreatedBy(PMPHAppUtil.getCurrentUserEnName());
                medicalCalculatorField.setUpdatedBy(PMPHAppUtil.getCurrentUserEnName());
                medicalCalculatorField.setCreatedTime(LocalDateTimeUtil.getNowAsString());
                medicalCalculatorField.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
                medicalCalculatorFieldMapper.saveBean(medicalCalculatorField);
            }
        }
        for (ReleasedMedicalCalculator releasedMedicalCalculator : releasedMedicalCalculators) {
            for (MedicalCalculatorLibField calculatorLibField : addList) {
                ReleasedMedicalCalculatorField releasedMedicalCalculatorField = new ReleasedMedicalCalculatorField();
                releasedMedicalCalculatorField.setMedicalCalcLibFieldId(calculatorLibField.getId());
                releasedMedicalCalculatorField.setKind(calculatorLibField.getKind());
                releasedMedicalCalculatorField.setName(calculatorLibField.getName());
                releasedMedicalCalculatorField.setIdent(calculatorLibField.getIdent());
                releasedMedicalCalculatorField.setMedicalCalcId(releasedMedicalCalculator.getId());
                releasedMedicalCalculatorField.setCreatedBy(PMPHAppUtil.getCurrentUserEnName());
                releasedMedicalCalculatorField.setUpdatedBy(PMPHAppUtil.getCurrentUserEnName());
                releasedMedicalCalculatorField.setCreatedTime(LocalDateTimeUtil.getNowAsString());
                releasedMedicalCalculatorField.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
                releasedMedicalCalculatorFieldMapper.saveBean(releasedMedicalCalculatorField);
            }
        }
        List<MedicalCalculator> calculatorList = new ArrayList<>();
        for (MedicalCalculator calculator : medicalCalculators) {
            calculator.setId(calculator.getId());
            calculatorList.add(calculator);
        }
        String calculatorId = calculatorList.stream().map(MedicalCalculator::getId).collect(Collectors.joining("','", "('", "')"));

        List<ReleasedMedicalCalculator> releasedCalculatorList = new ArrayList<>();
        for (ReleasedMedicalCalculator releasedCalculator : releasedMedicalCalculators) {
            releasedCalculator.setId(releasedCalculator.getId());
            releasedCalculatorList.add(releasedCalculator);
        }
        String releasedCalculatorId = releasedCalculatorList.stream().map(ReleasedMedicalCalculator::getId).collect(Collectors.joining("','", "('", "')"));
        for (MedicalCalculatorLibField medicalCalculatorLibField : updateList) {
            String libFieldSql = "update medical_calculator_lib_field set name ='" + medicalCalculatorLibField.getName() + "' , tag_id='" + medicalCalculatorLibField.getTagId() + "' where id ='" + medicalCalculatorLibField.getId() + "'";
            medicalCalculatorLibFieldMapper.executeUpdate(libFieldSql);

            String calculatorFieldSql = "update medical_calculator_field set name ='" + medicalCalculatorLibField.getName() + "' where medical_calc_id in" + calculatorId + " and medical_calc_lib_field_id ='" + medicalCalculatorLibField.getId() + "'";
            medicalCalculatorFieldMapper.executeUpdate(calculatorFieldSql);

            String releasedCalculatorFieldSql = "update released_medical_calculator_field set name ='" + medicalCalculatorLibField.getName() + "' where medical_calc_id in " + releasedCalculatorId + " and medical_calc_lib_field_id ='" + medicalCalculatorLibField.getId() + "'";
            releasedMedicalCalculatorFieldMapper.executeUpdate(releasedCalculatorFieldSql);
        }
        List<String> deleteIdList = deleteList.stream().map(MedicalCalculatorLibField::getId).collect(Collectors.toList());
        for (String deleteId : deleteIdList) {
            String knowledgeLibFieldId = deleteId;
            medicalCalculatorFieldMapper.deleteBeansByWherePart(" medical_calc_lib_field_id= '" + knowledgeLibFieldId + "'");
            releasedMedicalCalculatorFieldMapper.deleteBeansByWherePart(" medical_calc_lib_field_id= '" + knowledgeLibFieldId + "'");
            medicalCalculatorLibFieldMapper.deleteById(knowledgeLibFieldId);
        }
    }

    private List<MedicalCalculatorLibField> getUpdateList(List<MedicalCalculatorLibField> newList, List<MedicalCalculatorLibField> oldList) {
        Map<String, MedicalCalculatorLibField> oldMap = new HashMap<>();
        for (MedicalCalculatorLibField field : oldList) {
            oldMap.put(field.getId(), field);
        }
        List<MedicalCalculatorLibField> updateList = new ArrayList<>();
        for (MedicalCalculatorLibField field : newList) {
            boolean containId = oldMap.containsKey(field.getId());
            MedicalCalculatorLibField medicalCalculatorLibField = oldMap.get(field.getId());
            if (containId) {
                if (!medicalCalculatorLibField.getTagId().equals(field.getTagId())) {
                    List<MedicalCalculatorField> medicalCalculatorFields = medicalCalculatorFieldMapper.selectBeansByWherePart(" name='" + field.getName() + "'");
                    for (MedicalCalculatorField field1 : medicalCalculatorFields) {
                        if (StringUtils.isNotBlank(field1.getProperty())) {
                            throw new RuntimeException("当前公式已关联分类，不能修改关联类型");
                        }
                    }
                }
                if (!medicalCalculatorLibField.getName().equals(field.getName()) || !medicalCalculatorLibField.getTagId().equals(field.getTagId())) {
                    field.setName(field.getName());
                    field.setIdent(field.getIdent());
                    field.setTagId(field.getTagId());
                    field.setKind(field.getKind());
                    field.setKnowledgeLibId(field.getKnowledgeLibId());
                    updateList.add(field);
                }
            }
        }
        return updateList;
    }

    private List<MedicalCalculatorLibField> getDeleteList(List<MedicalCalculatorLibField> newList, List<MedicalCalculatorLibField> oldList) {
        Map<String, MedicalCalculatorLibField> oldMap = new HashMap<>();
        for (MedicalCalculatorLibField field : oldList) {
            oldMap.put(field.getId(), field);
        }
        for (MedicalCalculatorLibField field : newList) {
            boolean containId = oldMap.containsKey(field.getId());
            if (containId && field.getId() != null) {
                oldMap.remove(field.getId());
            }
        }
        return new ArrayList<>(oldMap.values());
    }

    private List<MedicalCalculatorLibField> getAddList(List<MedicalCalculatorLibField> newList) {
        List<MedicalCalculatorLibField> addList = new ArrayList<>();
        for (MedicalCalculatorLibField medicalCalculatorLibField : newList) {
            if ("".equals(medicalCalculatorLibField.getId()) || medicalCalculatorLibField.getId() == null) {
                medicalCalculatorLibField.setKind(medicalCalculatorLibField.getKind());
                medicalCalculatorLibField.setKnowledgeLibId(medicalCalculatorLibField.getKnowledgeLibId());
                medicalCalculatorLibField.setIdent(medicalCalculatorLibField.getIdent());
                medicalCalculatorLibField.setName(medicalCalculatorLibField.getName());
                medicalCalculatorLibField.setTagId(medicalCalculatorLibField.getTagId());
                addList.add(medicalCalculatorLibField);
            }
        }
        return addList;
    }

    private List<MedicalCalculatorLibField> getOldList(List<MedicalCalculatorLibField> medicalCalculatorLibFields) {
        List<MedicalCalculatorLibField> oldList = new ArrayList<>();
        for (MedicalCalculatorLibField medicalCalculatorLibField : medicalCalculatorLibFields) {
            medicalCalculatorLibField.setKind(medicalCalculatorLibField.getKind());
            medicalCalculatorLibField.setKnowledgeLibId(medicalCalculatorLibField.getKnowledgeLibId());
            medicalCalculatorLibField.setIdent(medicalCalculatorLibField.getIdent());
            medicalCalculatorLibField.setName(medicalCalculatorLibField.getName());
            medicalCalculatorLibField.setTagId(medicalCalculatorLibField.getTagId());
            oldList.add(medicalCalculatorLibField);
        }
        return oldList;
    }

    private List<MedicalCalculatorLibField> newList(String tableData) {
        List<MedicalCalculatorLibField> newList = new ArrayList<>();
        List<MedicalCalculatorLibField> fields = medicalCalculatorLibFieldMapper.selectAll();
        String knowledgeLibId = fields.get(0).getKnowledgeLibId();
        JSONArray objects = JSONArray.parseArray(tableData);
        for (int i = 0; i < objects.size(); i++) {
            JSONObject jsonObject = objects.getJSONObject(i);
            String id = jsonObject.getString("id");
            String name = jsonObject.getString("name");
            String tagName = jsonObject.getString("tagId");

            MedicalCalculatorLibField medicalCalculatorLibField = new MedicalCalculatorLibField();
            medicalCalculatorLibField.setKind(MedicalCalculatorField.CASCADE);
            medicalCalculatorLibField.setId(id);
            medicalCalculatorLibField.setKnowledgeLibId(knowledgeLibId);
            medicalCalculatorLibField.setIdent(1);
            medicalCalculatorLibField.setName(name);
            medicalCalculatorLibField.setTagId(tagName);
            medicalCalculatorLibField.setCreatedBy(PMPHAppUtil.getCurrentUserEnName());
            medicalCalculatorLibField.setUpdatedBy(PMPHAppUtil.getCurrentUserEnName());
            medicalCalculatorLibField.setCreatedTime(LocalDateTimeUtil.getNowAsString());
            medicalCalculatorLibField.setUpdatedTime(LocalDateTimeUtil.getNowAsString());
            newList.add(medicalCalculatorLibField);
        }
        return newList;
    }

    private String getTagId(String tagId) {
        tagId = tagId.substring(1, tagId.lastIndexOf("]"));
        if (tagId.indexOf("],") == -1) {
            tagId = tagId.substring(1, tagId.lastIndexOf("]"));
            if (tagId.indexOf(",") == -1) {
                return tagId;
            }
            tagId = tagId.split(",")[tagId.split(",").length - 1];
            return tagId;
        }
        String[] spl = tagId.split("],");
        List<String> stline = new ArrayList<>();
        for (String spStr : spl) {
            stline.add(spStr.split(",")[spStr.split(",").length - 1].replace("]", ""));
        }
        return stline.toString();
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void syncCalculator(String platformIds, String calculatorIds) {
        for (String calculatorId : calculatorIds.split(",")) {
            // 组装content内容;
            Map<String, Object> calculatorData = getReleaseCalculatorDataById(calculatorId);
            // 按照知识同步格式同步计算器;
            ReleasedKnowledge releasedKnowledge = parseCalculatorToKnowledge(calculatorId, calculatorData);
            // 遍历平台, 推送数据;
            for (String platformId : platformIds.split(",")) {
                rocketMQProducerService.sendKnowledge(platformId, releasedKnowledge, PMPHAppUtil.getCurrentUserEnName());
            }
        }
    }

    /**
     * 生成html文件时,图片转base64
     *
     * @param id
     * @return
     */
    public Map<String, Object> getReleaseCalculatorDataById(String id) {
        ReleasedMedicalCalculator releasedMedicalCalculator = releasedMedicalCalculatorMapper.selectById(id);
        Map<String, Object> map = releasedMedicalCalculatorData(releasedMedicalCalculator);
        return map;
    }

    public List<ReleasedMedicalCalculator> queryExportReleasedCalculatorList(String status, String platform, String name, String editor, String auditor, String type, String version, String updateTime) {
        String sql = "select c.*,mf.property  from released_medical_calculator c LEFT JOIN released_medical_calculator_field mf on mf.medical_calc_id=c.id where mf.kind =2 and c.deleted = 0";
        if (StringUtils.isNotBlank(name)) {
            sql += " and c.formula_name like '%" + name + "%'";
        }
        if (StringUtils.isNotBlank(editor)) {
            sql += " and c.id in (select knowledge_id from task_item where editor = '" + editor + "')";
        }
        if (StringUtils.isNotBlank(auditor)) {
            sql += " and c.id in (select knowledge_id from task_item where first_auditor = '" + auditor + "' or second_auditor = '" + auditor + "' or third_auditor = '" + auditor + "')";
        }
        if (StringUtils.isNotBlank(type)) {
            sql += " and c.formula_type = '" + type + "'";
        }
        if (StringUtils.isNotBlank(version)) {
            sql += " and c.version = '" + version + "'";
        }
        if (StringUtils.isNotBlank(platform) && !"[]".equals(platform) && !"\"\"".equals(platform)) {
            sql += " and mf.property like '%" + platform + "%'";
        }
        if (StringUtils.isNotBlank(updateTime)) {
            String startTime = (updateTime.split(",")[0].trim());
            String endTime = (updateTime.split(",")[1].trim());
            sql += " and c.updated_time >= '" + startTime + "' and c.updated_time <= '" + endTime + "'";

        }
        sql += " order by updated_time desc ";
        List<ReleasedMedicalCalculator> list = releasedMedicalCalculatorMapper.executeMultiSelect(sql);
        return list;
    }

    public void multiInsertTaskItem( String taskId, String remark, String username,List<ReleasedMedicalCalculator> medicalCalculatorList,Set<String> knowledgeInProcessIdSet) {

        for (ReleasedMedicalCalculator medicalCalculator : medicalCalculatorList) {
            if (!knowledgeInProcessIdSet.contains(medicalCalculator.getId())) {
                TaskItem taskItem = new TaskItem();
                taskItem.setTaskId(taskId);
                taskItem.setKnowledgeId(medicalCalculator.getId());
                taskItem.setName(medicalCalculator.getFormulaName());
                taskItem.setRemark(remark);
                // 查询上次关联的子任务, 字数;
                TaskItem dbTaskItem = taskItemService.getBaseMapper().selectBeanByWherePart(
                        " knowledge_id = '" + medicalCalculator.getId() + "' " +
                                " order by updated_time limit 1");
                if (Objects.nonNull(dbTaskItem)) {
                    taskItem.setWordsCount(dbTaskItem.getWordsCount());
                }
                taskItem.setType(TaskItem.TYPE_EDIT);
                taskService.saveTaskItem(taskItem, username);
            }
        }
    }

    private Map<String, Object> releasedMedicalCalculatorData(ReleasedMedicalCalculator releasedMedicalCalculator) {
        Map<String, Object> resultMap = new HashMap<>();
        String releasedCalculatorId = releasedMedicalCalculator.getId();
        String sql = "select * from released_medical_calculator_field where medical_calc_id='" + releasedCalculatorId + "' order by kind ";
        List<ReleasedMedicalCalculatorField> ReleasedMedicalCalculatorFields = releasedMedicalCalculatorFieldMapper.executeMultiSelect(sql);
        List<Map<String, Object>> fieldList = new ArrayList<>();
        for (ReleasedMedicalCalculatorField field : ReleasedMedicalCalculatorFields) {
            Map<String, Object> fieldMap = new HashMap<>();
            if (field.getKind() == MedicalCalculatorField.CASCADE) {
                List<MedicalCalculatorLibField> calculatorLibFields = medicalCalculatorLibFieldMapper.selectBeansByWherePart(" name= '" + field.getName() + "'");
                for (MedicalCalculatorLibField calculatorLibField : calculatorLibFields) {
                    if (calculatorLibField.getName().equals(field.getName())) {
                        fieldMap.put("name", field.getName());
                        fieldMap.put("kind", field.getKind());
                        fieldMap.put("property", field.getProperty());
                        fieldMap.put("ident", field.getIdent());
                        fieldMap.put("field_id", field.getMedicalCalcLibFieldId());
                        List<Map<String, Object>> resultList = getSubjectOptions(calculatorLibField.getTagId());
                        fieldMap.put("tagId", resultList);
                    }
                }
            } else {
                fieldMap.put("name", field.getName());
                fieldMap.put("kind", field.getKind());
                fieldMap.put("property", field.getProperty());
                fieldMap.put("ident", field.getIdent());
                fieldMap.put("field_id", field.getMedicalCalcLibFieldId());
            }
            fieldList.add(fieldMap);
        }
        resultMap.put("id", releasedMedicalCalculator.getId());
        resultMap.put("fields", fieldList);
        resultMap.put("describeContent", releasedMedicalCalculator.getDescribe());
        resultMap.put("version", releasedMedicalCalculator.getVersion());
        resultMap.put("type", releasedMedicalCalculator.getFormulaType());
        List<Map<String, Object>> computationList = getReleasedMedicalCalculatorDataMap(releasedCalculatorId);
        resultMap.put("medicalCalculatorData", computationList);
        List<Map<String, Object>> calculatorSoreList = getReleasedCalculatorSoreMap(releasedCalculatorId);
        resultMap.put("calculatorSore", calculatorSoreList);
        resultMap.put("formulaName", releasedMedicalCalculator.getFormulaName());
        resultMap.put("deleted", releasedMedicalCalculator.getDeleted());
        return resultMap;
    }

    private List<Map<String, Object>> getReleasedMedicalCalculatorDataMap(String releasedCalculatorId) {
        String sql = "select * from released_medical_calculator_computation where MEDICAL_CALC_ID = '" + releasedCalculatorId + "'";
        List<ReleasedMedicalCalculatorComputation> releasedComputations = releasedMedicalCalculatorComputationMapper.executeMultiSelect(sql);
        List<Map<String, Object>> computationList = new ArrayList<>();
        if (releasedComputations.size() <= 0) {
            return new ArrayList<>();
        }
        for (ReleasedMedicalCalculatorComputation releasedComputation : releasedComputations) {
            Map<String, Object> MedicalCalculatorMap = new HashMap<>();
            CalculateData calculateData = getReleasedCalculateDataMap(releasedComputation.getId());
            MedicalCalculatorMap.put("calculateData", calculateData);
            List<Map<String, Object>> sections = getReleasedSections(releasedComputation.getId());
            MedicalCalculatorMap.put("sections", sections);
            MedicalCalculatorMap.put("explain", releasedComputation.getGender());
            computationList.add(MedicalCalculatorMap);
        }
        return computationList;
    }

    private List<Map<String, Object>> getReleasedCalculatorSoreMap(String releasedCalculatorId) {
        String sql = "select * from released_medical_calculator_score_type where medical_calc_id = '" + releasedCalculatorId + "'";
        List<ReleasedMedicalCalculatorScoreType> ReleasedScoreTypes = releasedMedicalCalculatorScoreTypeMapper.executeMultiSelect(sql);
        List<Map<String, Object>> computationList = new ArrayList<>();
        if (ReleasedScoreTypes.size() <= 0) {
            return new ArrayList<>();
        }
        for (ReleasedMedicalCalculatorScoreType releasedScoreType : ReleasedScoreTypes) {
            Map<String, Object> calculatorScoreMap = new HashMap<>();
            List<Map<String, Object>> scoreData = getReleasedScoreData(releasedScoreType.getId());
            calculatorScoreMap.put("scoreData", scoreData);
            List<Map<String, Object>> sections = getReleasedSoreSections(releasedScoreType.getId());
            calculatorScoreMap.put("sections", sections);
            calculatorScoreMap.put("explain", releasedScoreType.getExplain());
            computationList.add(calculatorScoreMap);
        }
        return computationList;
    }

    private List<Map<String, Object>> getReleasedScoreData(String releasedCalculatorId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from released_medical_calculator_score where medical_calc_score_type_id = '" + releasedCalculatorId + "' order by sort";
        List<ReleasedMedicalCalculatorScore> releasedScores = releasedMedicalCalculatorScoreMapper.executeMultiSelect(sql);
        for (ReleasedMedicalCalculatorScore releasedScore : releasedScores) {
            Map<String, Object> scoreMap = new HashMap<>();
            scoreMap.put("id", releasedScore.getSort());
            List<Map<String, Object>> itemList = getReleasedScoreDataItemList(releasedScore.getId());
            scoreMap.put("items", itemList);
            scoreMap.put("multiple", releasedScore.getType().equals("true"));
            scoreMap.put("name", releasedScore.getName());
            resultList.add(scoreMap);
        }
        return resultList;
    }

    private List<Map<String, Object>> getReleasedScoreDataItemList(String id) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from released_medical_calculator_score_item where MEDICAL_CALC_SCORE_ID = '" + id + "' order by sort";
        List<ReleasedMedicalCalculatorScoreItem> releasedItems = releasedMedicalCalculatorScoreItemMapper.executeMultiSelect(sql);
        for (ReleasedMedicalCalculatorScoreItem releasedItem : releasedItems) {
            Map<String, Object> itemMap = new HashMap<>();
            itemMap.put("id", releasedItem.getSort());
            itemMap.put("score", releasedItem.getScore());
            itemMap.put("describe", releasedItem.getName());
            resultList.add(itemMap);
        }
        return resultList;
    }

    private CalculateData getReleasedCalculateDataMap(String releasedCalculatorId) {
        String sql = "select * from released_medical_calculator_computation where id = '" + releasedCalculatorId + "'";
        List<ReleasedMedicalCalculatorComputation> releasedComputations = releasedMedicalCalculatorComputationMapper.executeMultiSelect(sql);
        if (releasedComputations.size() <= 0) {
            return new CalculateData();
        }
        CalculateData calculateData = new CalculateData();
        for (ReleasedMedicalCalculatorComputation releasedComputation : releasedComputations) {
            String releasedComputationId = releasedComputation.getId();
            List<Map<String, Object>> formulaItems = getReleasedFormulaItems(releasedComputationId);
            calculateData.setFormulaItems(formulaItems);
            List<Map<String, Object>> formulaExpressionItems = getReleasedFormulaExpressionItems(releasedComputationId);
            calculateData.setFormulaExpressionItems(formulaExpressionItems);
            calculateData.setResultUnit(releasedComputation.getUnit());
        }
        return calculateData;
    }

    private List<Map<String, Object>> getReleasedFormulaItems(String releasedComputationId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from released_medical_calculator_computation_item where MEDICAL_CALC_COMP_ID = '" + releasedComputationId + "'";
        List<ReleasedMedicalCalculatorComputationItem> releasedItems = releasedMedicalCalculatorComputationItemMapper.executeMultiSelect(sql);
        for (ReleasedMedicalCalculatorComputationItem releasedItem : releasedItems) {
            Map<String, Object> itemMap = new LinkedHashMap<>();
            itemMap.put("item_id", releasedItem.getCode());
            itemMap.put("item_name", releasedItem.getName());
            itemMap.put("item_unit", releasedItem.getUnit());
            resultList.add(itemMap);
        }
        return resultList;
    }

    private List<Map<String, Object>> getReleasedFormulaExpressionItems(String releasedComputationId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from released_medical_calculator_computation_formulator where medical_calc_comp_id = '" + releasedComputationId + "'";
        List<ReleasedMedicalCalculatorComputationFormulator> releasedFormulators = releasedMedicalCalculatorComputationFormulatorMapper.executeMultiSelect(sql);
        for (ReleasedMedicalCalculatorComputationFormulator releasedFormulator : releasedFormulators) {
            Map<String, Object> formulatorMap = new HashMap<>();
            formulatorMap.put("item_expression", releasedFormulator.getFormulator());
            formulatorMap.put("item_type", releasedFormulator.getCondition());
            resultList.add(formulatorMap);
        }
        return resultList;
    }

    private List<Map<String, Object>> getReleasedSections(String releasedCalculatorId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from released_medical_calculator_result where medical_calc_comp_score_id = '" + releasedCalculatorId + "'";
        List<ReleasedMedicalCalculatorResult> releasedResults = releasedMedicalCalculatorResultMapper.executeMultiSelect(sql);
        for (ReleasedMedicalCalculatorResult releasedResult : releasedResults) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("explanation", releasedResult.getResultDesc());
            resultMap.put("id", releasedResult.getSort());
            resultMap.put("result", releasedResult.getResultDescFontColor());
            List<Map<String, Object>> sectionList = getReleasedSectionList(releasedResult.getId());
            resultMap.put("sections", sectionList);
            resultList.add(resultMap);
        }
        return resultList;
    }

    private List<Map<String, Object>> getReleasedSoreSections(String releasedCalculatorId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from released_medical_calculator_result where medical_calc_comp_score_id = '" + releasedCalculatorId + "'";
        List<ReleasedMedicalCalculatorResult> releasedResults = releasedMedicalCalculatorResultMapper.executeMultiSelect(sql);
        for (ReleasedMedicalCalculatorResult releasedResult : releasedResults) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("explanation", releasedResult.getResultDesc());
            resultMap.put("id", releasedResult.getSort());
            resultMap.put("result", releasedResult.getResultDescFontColor());
            List<Map<String, Object>> sectionList = getReleasedSectionList(releasedResult.getId());
            resultMap.put("sections", sectionList);
            resultList.add(resultMap);
        }
        return resultList;
    }


    private List<Map<String, Object>> getReleasedSectionList(String id) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        String sql = "select * from released_medical_calculator_result_item where medical_calc_result_id = '" + id + "'";
        List<ReleasedMedicalCalculatorResultItem> releasedItems = releasedMedicalCalculatorResultItemMapper.executeMultiSelect(sql);
        for (ReleasedMedicalCalculatorResultItem releasedItem : releasedItems) {
            Map<String, Object> itemMap = new HashMap<>();
            itemMap.put("condition", releasedItem.getCondition());
            itemMap.put("id", releasedItem.getSort());
            itemMap.put("relation", releasedItem.getRelation());
            itemMap.put("value", releasedItem.getValue());
            resultList.add(itemMap);
        }
        return resultList;
    }

    private void getField(MedicalCalculatorField field, Map<String, Object> fieldMap) {
        fieldMap.put("name", field.getName());
        fieldMap.put("kind", field.getKind());
        fieldMap.put("property", field.getProperty());
        fieldMap.put("ident", field.getIdent());
        fieldMap.put("field_id", field.getMedicalCalcLibFieldId());
    }

    private ReleasedKnowledge parseCalculatorToKnowledge(String calculatorId, Map<String, Object> calculatorData) {
        List<Map<String, Object>> fieldList = (List<Map<String, Object>>) calculatorData.get("fields");
        // 结果说明, 单独取出;
        Object resultDescription = fieldList.stream().filter(item -> Objects.equals(item.get("name"), "结果说明")).map(item -> Objects.isNull(item.get("property")) ? "" : item.get("property")).findFirst().get();

        calculatorData.put("resultDescription", resultDescription);
        // 参考文献, 单独取出;
        Object reference = fieldList.stream().filter(item -> Objects.equals(item.get("name"), "参考文献")).map(item -> Objects.isNull(item.get("property")) ? "" : item.get("property")).findFirst().get();
        calculatorData.put("reference", reference);
        // 组装H5页面内容;
//        template.body().child(0).text("let data = " + JSON.toJSONString(calculatorData));
        // content内容;
//        String content = StringEscapeUtils.unescapeJava(template.outerHtml()).replaceAll("\r", "");
        ReleasedKnowledge releasedKnowledge = new ReleasedKnowledge();
        releasedKnowledge.setKnowledgeLibId(KnowledgeLib.CALCULATOR_LIB_ID);
        releasedKnowledge.setKnowledgeLibName(MedicalCalculator.CALCULATOR_LIB_NAME);
        releasedKnowledge.setId(calculatorId);
        if ((Integer) calculatorData.get("deleted") == 1) {
            releasedKnowledge.setSyncOperation(ReleasedKnowledge.SYNC_OPERATION_DELETE);
        }
        releasedKnowledge.setName((String) calculatorData.get("formulaName"));
        Integer version = (Integer) calculatorData.get("version");
        if (Objects.isNull(version)) {
            version = 1;
        }
        releasedKnowledge.setVersion(version);
        ArrayList<KnowledgeField> knowledgeFieldList = new ArrayList<>();

        for (int i = 0; i < fieldList.size(); i++) {
            Map<String, Object> map = fieldList.get(i);
            MedicalCalculatorField medicalCalculatorField = new MedicalCalculatorField();
            medicalCalculatorField.setName((String) map.get("name"));
            medicalCalculatorField.setProperty((String) map.get("property"));
            medicalCalculatorField.setKind((Integer) map.get("kind"));
            medicalCalculatorField.setMedicalCalcLibFieldId((String) map.get("field_id"));
            medicalCalculatorField.setIdent((Integer) map.get("ident"));

            ReleasedKnowledgeField releasedKnowledgeField = new ReleasedKnowledgeField();
            releasedKnowledgeField.setRequired(false);
            releasedKnowledgeField.setIndex(i);
            releasedKnowledgeField.setKnowledgeLibFieldId(medicalCalculatorField.getMedicalCalcLibFieldId());
            releasedKnowledgeField.setName(medicalCalculatorField.getName());
            releasedKnowledgeField.setKnowledgeId(calculatorId);
            releasedKnowledgeField.setDisplayName(medicalCalculatorField.getName());
            if (medicalCalculatorField.getKind() == MedicalCalculatorField.CASCADE) {
                releasedKnowledgeField.setKind(KnowledgeLibField.FIELD_KIND_REFERENCE);
                //关联tag, 数据库存储为双重数组, 内层数组存储级联选中项, 只取最后一项;
                releasedKnowledgeField.setProperty(medicalCalculatorField.getProperty());
            } else if (medicalCalculatorField.getKind() == MedicalCalculatorField.INPUT_BOX || medicalCalculatorField.getKind() == MedicalCalculatorField.EXPLAIN) {
                releasedKnowledgeField.setKind(KnowledgeLibField.FIELD_KIND_STRINGTEXT);
                releasedKnowledgeField.setProperty(medicalCalculatorField.getProperty());
            } else if (medicalCalculatorField.getKind() == MedicalCalculatorField.DROP_DOWN) {
                // 关联平台, jsonArray 转为 ; 分割字符串 (只能关联平台)
                releasedKnowledgeField.setKind(KnowledgeLibField.FIELD_KIND_ASSOCIATE_PLATFORM);
                releasedKnowledgeField.setProperty(medicalCalculatorField.getProperty());
            } else if (medicalCalculatorField.getKind() == MedicalCalculatorField.RICH_TEXT) {
                releasedKnowledgeField.setKind(KnowledgeLibField.FIELD_KIND_RICHEDITOR);
                releasedKnowledgeField.setProperty(medicalCalculatorField.getProperty());
            } else if (medicalCalculatorField.getKind() == MedicalCalculatorField.TEXT_FIELD) {
                releasedKnowledgeField.setKind(KnowledgeLibField.FIELD_KIND_TEXTAREA);
                releasedKnowledgeField.setProperty(medicalCalculatorField.getProperty());
            } else if (medicalCalculatorField.getKind() == MedicalCalculatorField.MORE_VALUE) {
                releasedKnowledgeField.setKind(KnowledgeLibField.FIELD_KIND_MULTI_VALUE_INPUT);
                releasedKnowledgeField.setProperty(medicalCalculatorField.getProperty());
            } else {
                releasedKnowledgeField.setKind(KnowledgeLibField.FIELD_KIND_STRINGTEXT);
                releasedKnowledgeField.setProperty(medicalCalculatorField.getProperty());
            }
            knowledgeFieldList.add(releasedKnowledgeField);
        }
        // 添加content字段;
        ReleasedKnowledgeField releasedKnowledgeField = new ReleasedKnowledgeField();
        releasedKnowledgeField.setRequired(false);
        releasedKnowledgeField.setKnowledgeLibFieldId(MedicalCalculator.CALCULATOR_LIB_FIELD_ID_CONTENT);
        releasedKnowledgeField.setName("content");
        releasedKnowledgeField.setKnowledgeId(calculatorId);
        releasedKnowledgeField.setDisplayName("content");
        releasedKnowledgeField.setKind(KnowledgeLibField.CALCULATOR_FIELD_KIND_H5);
        releasedKnowledgeField.setProperty("/pmph/action/file/getFile?filename=file/calculator/" + calculatorData.get("id") + ".html");
        releasedKnowledgeField.setIndex(knowledgeFieldList.size());
        knowledgeFieldList.add(releasedKnowledgeField);
        releasedKnowledge.setKnowledgeFieldList(knowledgeFieldList);
        return releasedKnowledge;
    }

    public List<MedicalCalculatorLibField> getMedicalCalculatorLibField() {
        List<MedicalCalculatorLibField> medicalCalculatorLibFields = medicalCalculatorLibFieldMapper.selectAll();
        return medicalCalculatorLibFields;
    }

    public List<MedicalCalculatorLibField> getMedicalCalculatorLibFieldSql(String sql) {
        List<MedicalCalculatorLibField> medicalCalculatorLibFields = medicalCalculatorLibFieldMapper.executeMultiSelect(sql);
        return medicalCalculatorLibFields;
    }

    public List<ReleasedMedicalCalculator> getReleasedMedicalCalculator() {
        List<ReleasedMedicalCalculator> releasedMedicalCalculators = releasedMedicalCalculatorMapper.selectAll();
        return releasedMedicalCalculators;
    }

    public List<ReleasedMedicalCalculator> getReleasedMedicalCalculatorSql(String sql) {
        List<ReleasedMedicalCalculator> releasedMedicalCalculators = releasedMedicalCalculatorMapper.executeMultiSelect(sql);
        return releasedMedicalCalculators;
    }

    public MedicalCalculator getMedicalCalculator(String id) {
        MedicalCalculator medicalCalculator = medicalCalculatorMapper.selectById(id);
        return medicalCalculator;
    }

    public ReleasedMedicalCalculator getReleasedMedicalCalculatorById(String id) {
        ReleasedMedicalCalculator releasedMedicalCalculator = releasedMedicalCalculatorMapper.selectById(id);
        return releasedMedicalCalculator;
    }

    public List<MedicalCalculatorLibField> getMedicalCalculatorLibFieldByWhereStr(String whereStr) {
        List<MedicalCalculatorLibField> medicalCalculatorLibFields = medicalCalculatorLibFieldMapper.selectBeansByWherePart(whereStr);

        return medicalCalculatorLibFields;
    }

    public List<ReleasedMedicalCalculatorField> getReleasedMedicalCalculatorFieldByWhereStr(String whereStr) {
        List<ReleasedMedicalCalculatorField> releasedMedicalCalculatorFields = releasedMedicalCalculatorFieldMapper.selectBeansByWherePart(whereStr);
        return releasedMedicalCalculatorFields;
    }

    public List<MedicalCalculatorField> getMedicalCalculatorField(String whereStr) {
        List<MedicalCalculatorField> medicalCalculatorFields = medicalCalculatorFieldMapper.selectBeansByWherePart(whereStr);
        return medicalCalculatorFields;
    }

    public List<MedicalCalculatorComputation> getMedicalCalculatorComputation(String whereStr) {
        List<MedicalCalculatorComputation> medicalCalculatorComputations = medicalCalculatorComputationMapper.selectBeansByWherePart(whereStr);
        return medicalCalculatorComputations;
    }

    public List<MedicalCalculatorComputationFormulator> getMedicalCalculatorComputationFormulator(String whereStr) {
        List<MedicalCalculatorComputationFormulator> medicalCalculatorComputationFormulators = medicalCalculatorComputationFormulatorMapper.selectBeansByWherePart(whereStr);
        return medicalCalculatorComputationFormulators;
    }

    public List<MedicalCalculatorComputationItem> getMedicalCalculatorComputationItem(String whereStr) {
        List<MedicalCalculatorComputationItem> medicalCalculatorComputationItems = medicalCalculatorComputationItemMapper.selectBeansByWherePart(whereStr);
        return medicalCalculatorComputationItems;
    }

    public List<MedicalCalculatorScoreType> getMedicalCalculatorScoreType(String whereStr) {
        List<MedicalCalculatorScoreType> medicalCalculatorScoreTypes = medicalCalculatorScoreTypeMapper.selectBeansByWherePart(whereStr);
        return medicalCalculatorScoreTypes;
    }

    public List<MedicalCalculatorScore> getMedicalCalculatorScore(String whereStr) {
        List<MedicalCalculatorScore> medicalCalculatorScores = medicalCalculatorScoreMapper.selectBeansByWherePart(whereStr);
        return medicalCalculatorScores;
    }

    public List<MedicalCalculatorScoreItem> getMedicalCalculatorScoreItem(String whereStr) {
        List<MedicalCalculatorScoreItem> medicalCalculatorScoreItems = medicalCalculatorScoreItemMapper.selectBeansByWherePart(whereStr);

        return medicalCalculatorScoreItems;
    }

    public void ReleasedCalcDeleteById(String id, String status) {
        if (StringUtils.equals(status, "published")) {
            ReleasedMedicalCalculator releasedMedicalCalculator = releasedMedicalCalculatorMapper.selectById(id);
            releasedMedicalCalculator.setVersion(releasedMedicalCalculator.getVersion() + 1);
            releasedMedicalCalculator.setDeleted(ReleasedMedicalCalculator.DELETED_YES);
            // 修改知识
            releasedMedicalCalculatorMapper.updateById(releasedMedicalCalculator);
            HistoryUtils.save(id, releasedMedicalCalculator.getFormulaName(), History.OPERATE_DELETE, History.OPERATE_RESULT_SUCCESS);

            // 同步逻辑删除子任务,如果该知识有修订的,不允许删除,所以不加status = 8 的判断
            LambdaUpdateWrapper<TaskItem> taskItemUpdateWrapper = Wrappers.lambdaUpdate();
            taskItemUpdateWrapper.set(TaskItem::getDeleted, TaskItem.DELETED);
            taskItemUpdateWrapper.eq(TaskItem::getKnowledgeId, id);
            taskItemService.update(taskItemUpdateWrapper);
            List<PlatformKnowledgeLib> platformKnowledgeLibs = platformKnowledgeLibMapper.lambdaQuery().eq(PlatformKnowledgeLib::getKnowledgeLibId, KnowledgeLib.CALCULATOR_LIB_ID).list();
            String platformIds = platformKnowledgeLibs.stream().map(PlatformKnowledgeLib::getPlatformId).collect(Collectors.joining(","));
            syncCalculator(platformIds, id);
        }
    }

    public Page<ReleasedMedicalCalculator> ReleasedCalcDeleteData(int currentPage, int pageNum, String name, String updatedTime, String updatedBy) {
        LambdaQueryWrapper<ReleasedMedicalCalculator> query = Wrappers.lambdaQuery(ReleasedMedicalCalculator.class)
                .like(StringUtils.isNoneBlank(name), ReleasedMedicalCalculator::getFormulaName, name)
                .eq(ReleasedMedicalCalculator::getDeleted, ReleasedMedicalCalculator.DELETED_YES)
                .eq(StringUtils.isNoneBlank(updatedBy), ReleasedMedicalCalculator::getUpdatedBy, updatedBy);
        if (StringUtils.isNotEmpty(updatedTime)) {
            query = query.ge(ReleasedMedicalCalculator::getUpdatedTime, updatedTime.split(",")[0].trim())
                    .le(ReleasedMedicalCalculator::getUpdatedTime, updatedTime.split(",")[1].trim());
        }
        Page<ReleasedMedicalCalculator> page = releasedMedicalCalculatorMapper.selectPage(new Page<>(currentPage, pageNum), query);
        return page;
    }

    public void recoverReleasedMedicalCalculator(String ids) {
        String[] idArray = ids.split(",");
        for (String id : idArray) {
            // 修改发布医学计算器 delete version
            ReleasedMedicalCalculator releasedMedicalCalculator = releasedMedicalCalculatorMapper.selectById(id);
            releasedMedicalCalculator.setDeleted(ReleasedKnowledge.DELETED_NO);
            releasedMedicalCalculator.setVersion(releasedMedicalCalculator.getVersion() + 1);
            releasedMedicalCalculatorMapper.updateById(releasedMedicalCalculator);
            HistoryUtils.save(id, releasedMedicalCalculator.getFormulaName(), History.OPERATE_RECOVER, History.OPERATE_RESULT_SUCCESS);
            // 恢复子任务
            taskItemService.getBaseMapper().executeUpdate("update task_item set deleted = " + TaskItem.NO_DELETED + ", updated_time='" + LocalDateTimeUtil.getNowAsString() + "' where knowledge_id = '" + id + "'");
            //修改同步状态
            knowledgeSyncStatusService.getBaseMapper().executeUpdate("update knowledge_sync_status set kind = " + KnowledgeSyncStatus.FAILED_KIND_WAITING + " where knowledge_id = '" + id + "'");
            List<PlatformKnowledgeLib> platformKnowledgeLibs = platformKnowledgeLibMapper.lambdaQuery().eq(PlatformKnowledgeLib::getKnowledgeLibId, KnowledgeLib.CALCULATOR_LIB_ID).list();
            String platformIds = platformKnowledgeLibs.stream().map(PlatformKnowledgeLib::getPlatformId).collect(Collectors.joining(","));
            syncCalculator(platformIds, id);
        }
    }

    public void deleteReleasedMedicalCalculator(String id, String name, String updatedTime, String updatedBy, String operationType) {
        if ("all".equals(operationType)) {
            LambdaQueryWrapper<ReleasedMedicalCalculator> query = Wrappers.lambdaQuery(ReleasedMedicalCalculator.class)
                    .like(StringUtils.isNoneBlank(name), ReleasedMedicalCalculator::getFormulaName, name)
                    .eq(ReleasedMedicalCalculator::getDeleted, ReleasedMedicalCalculator.DELETED_YES)
                    .eq(StringUtils.isNoneBlank(updatedBy), ReleasedMedicalCalculator::getUpdatedBy, updatedBy);
            if (StringUtils.isNotEmpty(updatedTime)) {
                query = query.ge(ReleasedMedicalCalculator::getUpdatedTime, updatedTime.split(",")[0].trim())
                        .le(ReleasedMedicalCalculator::getUpdatedTime, updatedTime.split(",")[1].trim());
            }
            List<ReleasedMedicalCalculator> records = releasedMedicalCalculatorMapper.selectPage(new Page<>(), query).getRecords();
            if (CollectionUtils.isNotEmpty(records)) {
                records.forEach(releasedMedicalCalculator -> {
                    taskItemService.remove(Wrappers.lambdaQuery(TaskItem.class).eq(TaskItem::getKnowledgeId, releasedMedicalCalculator.getId()));
                    deleteReleasedCalculator(releasedMedicalCalculator.getId());
                });
            }
        } else {
            taskItemService.remove(Wrappers.lambdaQuery(TaskItem.class).eq(TaskItem::getKnowledgeId, id));
            deleteReleasedCalculator(id);
        }

    }

    private boolean hasUnConfirmedNameSuggestion(String calculatorId) {
        // 根据知识id 校验, 当前绑定子任务是否存在名称待确认;
        List<TaskItem> taskItemList = taskItemService.lambdaQuery()
                .eq(TaskItem::getKnowledgeId, calculatorId)
                .eq(TaskItem::getStatus, TaskItem.STATUS_PASS).list();
        for (TaskItem taskItem : taskItemList) {
            if (taskItem.getNameSuggestion().hasUnconfirmedNameSuggestion()) {
                taskItem.setPress(true);
                taskItemService.updateById(taskItem);
                return true;
            }
        }
        return false;
    }
}
